<!--
/**
 * form.js
 *
 * This javascript component allows for form validation and manipulation through PHP (in combination with the Webline_Form PHP components).
 *
 * <b>Variables</b>
 *
 * <ul>
 *   <li>weblineFormDebug (int|false) = 0<br><br>Show debug information in console or not. To disable set it to false, To enable set a number from 0 (min) - 6 (max)<br><br></li>
 *   <li>arrWeblineForm (array) = new Array()<br><br>Array that holds the forms<br><br></li>
 *   <li>arrWeblineFormListeners (array) = new Array()<br><br>Array that holds the ids of the fields which have an event handler set by weblineFormAddListener<br><br></li>
 *   <li>arrWeblineFormValidateRadios (array) = new Array()<br><br>Array that holds the validation information for radio buttons (Jan, please explain...) (???)<br><br></li>
 *   <li>arrWeblineFormOriginalValues (array) = []<br><br>Array that holds the original values of a form when first initialized<br><br></li>
 *   <li>arrWeblineFormLastValues (array) = []<br><br>Array that holds the last values of a field when it has been validated before. If a field is present in this array, the result of the validation is present in the array arrWeblineLastTests. The purpose of this array is to not re-check fields when we already have the result, and its value did not change from the previous value.<br><br></li>
 *   <li>arrWeblineFormLastAjaxTests (array) = []<br><br>Array that holds the values of the ajax tests for this field<br><br></li>
 *   <li>arrWeblineFormLastTests (array) = []<br><br>Array that holds the values of the last tests<br><br></li>
 *   <li>arrWeblineFormMessages (array) = []<br><br>Array that holds the messages for the forms<br><br></li>
 *   <li>arrWeblineFormDepends (array) = []<br><br>Array that holds the dependency information for the forms<br><br></li>
 *   <li>weblineFormActivated (int) = ""<br><br>String that represents the ID of the form currently being processed from array arrWeblineForm<br><br></li>
 *   <li>weblineFormSearchActivated (string) = ""<br><br>String that represents the ID of the field currently being searched by AJAX request<br><br></li>
 *   <li>weblineFormDivFieldActivated (string) = ""<br><br>String that represents the ID of the field currently being submitted as a DIV=>Field conversion<br><br></li>
 *   <li>weblineFormTimerID (int) = 0<br><br>ID of the timer used to delay validation on certain fields<br><br></li>
 *   <li>weblineFormSearchTimerID (int) = 0<br><br>ID of the timer used to delay search on certain fields<br><br></li>
 *   <li>weblineFormColorValid (string) = "#bfffbf"<br><br>Color information in case a field is VALID<br><br></li>
 *   <li>weblineFormColorNormal (string) = "#ffffff"<br><br>Color information in case a field is not checked, or empty in case it is not required<br><br></li>
 *   <li>weblineFormColorInvalid (string) = "#ffbfbf"<br><br>Color information in case a field is INVALID<br><br></li>
 * </ul>
 *
 * <b>Triggers</b>
 *
 * This component contains a few triggers. These triggers are called at specific moments and can be used to write some extended code for the form handling.
 *
 * <ul>
 *   <li>weblineFormTriggerValidated(fieldId,result)<br><br>This function is called after the validation of each field. It will pas the fields ID and the result as a boolean to this trigger.</li>
 *   <li>weblineFormTriggerGroups(groupCount)<br><br>This function is called after each form validation and will pass the number of groups visible on the page. This can be used to hide or show extra information depending on the number of groups.</li>
 * </ul>
 *
 * @package Jscripts
 * @author Webline BVBA <info@webline.be>
 * @copyright Webline BVBA
 * @link http://www.webline.be/  www.webline.be
 */

var weblineFormDebug = false;
var arrWeblineForm = new Array();
var arrWeblineFormListeners = new Array();
var arrWeblineFormValidateRadios = new Array();
var arrWeblineFormOriginalValues = [];
var arrWeblineFormLastValues = [];
var arrWeblineFormLastAjaxTests = [];
var arrWeblineFormLastTests = [];
var arrWeblineFormMessages = [];
var arrWeblineFormDepends = [];
var weblineFormActivated = "";
var weblineFormSearchActivated = "";
var weblineFormDivFieldActivated = "";
var weblineFormTimerID = 0;
var weblineFormSearchTimerID = 0;
var weblineFormColorValid = "#bfffbf";
var weblineFormColorNormal = "#ffffff";
var weblineFormColorInvalid = "#ffbfbf";

/**
 * Initial call for the form validation. This function will loop all forms present in arrWeblineForm and load some general settings for each form like the icons, colors and id of the submit button.
 *
 * @access public
 * @return void
 * @uses weblineFormToggleButton()
 * @uses weblineFormGroupInit()
 * @uses weblineFormValidate()
 */
function weblineFormInit() {
	
	weblineFormDebugGroup("weblineFormInit");
	
	weblineFormDebugConsole("weblineFormInit: Initializing " + arrWeblineForm.length + " form(s) on this page");
	
	// Loop the forms

	for(var i=0; i<arrWeblineForm.length; i++) {
	
		// Get the formid
	
		var formid = arrWeblineForm[i]['formid'];
		
		// Debug information

		weblineFormDebugConsole("weblineFormInit: Processing form with key " + i + " and id " + formid);
		
		// Set the active form
		
		weblineFormActivated = i;
	
		// Disable the button

		weblineFormToggleButton(false);
		
		// Check form
		
		weblineFormValidate();
		
		// Initialize groups
		
		weblineFormGroupInit(formid);
		
		// Initialize search/autocomplete
		
		weblineFormSearchInit(formid);
	
	} // end for
	
	WeblineConsole.groupEnd();

} // end function

/**
 * This function is called on each event set by the weblineFormAddListener function
 *
 * @param event Event object for the field that has an event
 * @access public
 * @return void
 * @uses weblineFormToggleButton()
 * @uses weblineFormValidate()
 */
function weblineFormCall(event) {

	// Find the form to which this field belongs to, starting from an event
	
	var objForm = null;
	var objTarget = null;
	
	if(event.target) { // FF way
	
		objTarget = event.target;
		objForm = objTarget.form;
	
	}else{ // IE way
		
		objTarget = window.event.srcElement;
		
		node = objTarget;
	
		while(node.nodeName!="FORM" && node.parentNode) {
	
			node = node.parentNode;
			
		} // end while
	
		if(node!=objTarget) {
	
			objForm = node;

		} // end if
	
	} // end if

	// Update the active form variable, so we know which form to validate on this call
	
	if(objForm!=null) {
	
		for(var i=0; i<arrWeblineForm.length; i++) {
		
			if(arrWeblineForm[i]['formid']==objTarget.form.id) {
	
				weblineFormActivated = i;
				
			} // end if
			
		} // end for
	
	} // end if

	weblineFormDebugConsole("weblineFormCall: form " + arrWeblineForm[weblineFormActivated]['formid']);
	
	// Disable the button

	weblineFormToggleButton(false);
	
	// Clear timer if it has been set

	if(weblineFormTimerID) {

		clearTimeout(weblineFormTimerID);
		weblineFormTimerID  = 0;

	} // end if
	
	// Check for fields that should be delayed
	
	var arrDelay = arrWeblineForm[weblineFormActivated]['delay'];
	
	if(arrDelay.length>0) {

		weblineFormDebugConsole("weblineFormCall: Number of delays: " + arrDelay.length);
		
		var active_timer = false;

		for(var i=0; i<arrDelay.length; i++) {
			/*
			if(event.target.id==arrDelay[i]) {

				weblineFormDebugConsole("weblineFormCall: Activating delay for: " + arrDelay[i]);

				active_timer = true;
	
			} // end if
			*/
			
			
			// FF / Chrome / ...
			
			if(event.target && (event.target.id==arrDelay[i])) {

				weblineFormDebugConsole("weblineFormCall: Activating delay for: " + arrDelay[i]);
				active_timer = true;
				
			}else if(typeof(window.event)!="undefined" && window.event.srcElement.id==arrDelay[i]) {

				weblineFormDebugConsole("weblineFormCall: Activating delay for: " + arrDelay[i]);
				active_timer = true;			
			
			} // end if			
			
		} // end for
	
		if(active_timer) {

			weblineFormTimerID = setTimeout("weblineFormValidate()", 1000);

		}else{

			weblineFormValidate();

		} // end if
		
	}else{

		weblineFormValidate();
	
	} // end if
	
} // end function

/**
 * Start the validation of the currently active form. This function will retreive and array of fields and pass it on to the weblineFormValidateFields function
 *
 * @access public
 * @return void
 * @uses weblineFormGetFields()
 * @uses weblineFormValidateField()
 * @uses weblineFormToggleButton()
 * @uses weblineFormTrigger()
 */
function weblineFormValidate() {

	weblineFormDebugConsole("[" + arrWeblineForm[weblineFormActivated]['formid'] + "] weblineFormValidate: Start validation for this form",1);
	
	// Get an array of fields will all their settings

	var arrFields = weblineFormGetFields(arrWeblineForm[weblineFormActivated]['formid']);
	
	// Assume all fields are OK. If one field is not OK, this will be set to false
	
	var allFieldsOK = true;
	
	// Loop the array of fields and start checking
	
	for(var i=0; i<arrFields.length; i++) {
	
		// Load the array with all settings for this field
	
		var arrField = arrFields[i];
		
		// Test the field
		
		var testField = weblineFormValidateField(arrField[0],arrField[1],arrField[2],arrField[3],arrField[4],arrField[5],arrField[6],arrField[7]);
		
		// If NOK, mark the variable allFieldsOK as false
		
		if(testField==false) {
		
			allFieldsOK = false;
			
		} // end if
	
	} // end for

	if(allFieldsOK) {

		weblineFormToggleButton(true);

	}else{

		weblineFormToggleButton(false);

	} // end if
	
	// Launch some trigger functions
	
	weblineFormTrigger("groups");
	
} // end function

/**
 * Triggers
 *
 * @access private
 * @param string Type of the trigger. At this point only "groups" is working
 * @return void
 * @uses weblineFormGroupCount()
 * @uses weblineFormTriggerGroups()
 * @uses weblineFormTriggerValidated()
 */
function weblineFormTrigger(triggerType,fieldId,result) {
	
	weblineFormDebugConsole("weblineFormTrigger: Trigger " + triggerType + " function");

	if(triggerType=="groups") {

		if(typeof weblineFormTriggerGroups=="function") {

			weblineFormDebugConsole("weblineFormTrigger: Launching trigger function weblineFormTriggerGroups",1);
		
			var groupCount = weblineFormGroupCount();
	
			weblineFormTriggerGroups(groupCount);
	
		} // end if
	
	} // end if

	if(triggerType=="validated") {

		if(typeof weblineFormTriggerValidated=="function") {

			weblineFormDebugConsole("weblineFormTrigger: Launching trigger function weblineFormTriggerValidated",1);
		
			weblineFormTriggerValidated(fieldId,result);
	
		} // end if
	
	} // end if
	
} // end function

/**
 * Initialize the groups
 *
 * For now, this will only update the add button with the correct link.
 *
 * @param string ID of the form your want the groups to be initialized
 * @access private
 * @return void
 * @uses weblineFormGroupUpdateAddButton()
 */
function weblineFormGroupInit(formId) {

	weblineFormDebugGroup("weblineFormGroupInit");
	
	weblineFormDebugConsole("[" + formId + "] weblineFormGroupInit: Initialize groups",1);
		
	// Get the fields and start looping them to find the different groups left behind
	
	var lastGroup = "";
	
	for(var i=0; i<arrWeblineForm[weblineFormActivated]['groups'].length; i++) {
	
		//weblineFormDebugConsole(arrWeblineForm[weblineFormActivated]['groups'][i]);
		
		if(arrWeblineForm[weblineFormActivated]['groups'][i]!="removed") {
	
			var arrGroup = arrWeblineForm[weblineFormActivated]['groups'][i].split("|");
		
			var objGroup = document.getElementById(arrGroup[1]);
		
			if(objGroup.style.display!="none" && objGroup.id!=lastGroup) {
	
				lastGroup = objGroup.id;
				
				// Update the button
				
				weblineFormGroupUpdateAddButton(objGroup.id);
			
			} // end if
		
			// Check if this group is required, if so, hide the remove button
		
			if(arrWeblineForm[weblineFormActivated]['group_required'][objGroup.id]!=undefined) {
			
				// Search for the delete button
	
				var objButton = weblineFormGroupGetRemoveButton(objGroup);
				
				// If button found => hide it
				
				if(objButton!=false) {
				
					objButton.style.display = "none";

				} // end if
		
			} // end if
			
		} // end if
	
	} // end for
	
	WeblineConsole.groupEnd();

} // end function

/**
 * Count number of active groups
 *
 * @access private
 * @return int Number of forms
 */
function weblineFormGroupCount() {
	
	weblineFormDebugConsole("[" + arrWeblineForm[weblineFormActivated]['formid'] + "] weblineFormGroupCount: Count number of active groups",1);
		
	// Get the fields and start looping them to find the different groups left behind
	
	var groupCount = 0;
	var lastGroup = "";
	
	for(var i=0; i<arrWeblineForm[weblineFormActivated]['groups'].length; i++) {
	
		//weblineFormDebugConsole(arrWeblineForm[weblineFormActivated]['groups'][i]);
		
		if(arrWeblineForm[weblineFormActivated]['groups'][i]!="removed") {
	
			var arrGroup = arrWeblineForm[weblineFormActivated]['groups'][i].split("|");
		
			var objGroup = document.getElementById(arrGroup[1]);
		
			if(objGroup.style.display!="none" && objGroup.id!=lastGroup) {
	
				groupCount++;
				lastGroup = objGroup.id;
			
			} // end if
			
		} // end if
	
	} // end for
	
	return groupCount;

} // end function

/**
 * Process the form and return an array of the fields with all their settings
 *
 * @param string ID of the form
 * @access private
 * @return array Array of fields
 * @uses weblineFormGetFieldSettings()
 */
function weblineFormGetFields(formId) {

	weblineFormDebugConsole("[" + formId + "] weblineFormGetFields: Load the fields for form with id " + formId,1);

	var arrFields = [];
	var iField = 0;
	var objForm = document.getElementById(formId);
	
	for(i=0;i<objForm.elements.length;i++) {
	
		if(objForm.elements[i].id!='') {
	
			arrFields[iField++] = weblineFormGetFieldSettings(objForm.elements[i].id);
	
		} // end if
	
	} // end for
	
	return arrFields;

} // end function

/**
 * Get the settings for a specific field
 *
 * @param string ID of the field
 * @access private
 * @return array Array of fields
 */
function weblineFormGetFieldSettings(fieldId) {

	weblineFormDebugConsole("[" + fieldId + "] weblineFormGetFieldSettings: Load the settings for field with id " + fieldId,3);
	
	var objField = document.getElementById(fieldId);
	
	var field_id = fieldId;			
	var field_required = false;
	var field_unique = false;	
	var field_search = false;	
	var field_exists = false;		
	var field_depends = false;
	var field_equals = false;
	var field_validations = false;
	var field_group = "";
	
	if(objField.getAttribute("required")) {

		if(objField.getAttribute("required")=="true") {
		
			field_required = true;
			
		} // end if
	
	} // end if

	if(objField.getAttribute("unique")) {
		
		field_unique = objField.getAttribute("unique");
	
	} // end if

	if(objField.getAttribute("exists")) {
		
		field_exists = objField.getAttribute("exists");
	
	} // end if

	if(objField.getAttribute("equals")) {
		
		field_equals = objField.getAttribute("equals");
	
	} // end if

	if(objField.getAttribute("depends")) {
		
		field_depends = objField.getAttribute("depends");
	
	} // end if
	
	// check for overrides from the PHP module:

	if(arrWeblineForm[weblineFormActivated]['required'].length>0) {

		for(var j=0; j<arrWeblineForm[weblineFormActivated]['required'].length; j++) {
		
			if(objField.type=="radio") {
			
				var dynamicFieldId = arrWeblineForm[weblineFormActivated]['required'][j];

				//weblineFormDebugConsole("check field against array: " + field_id.substr(0,dynamicFieldId.length-1) + " == " + dynamicFieldId);
			
				if(field_id.substr(0,dynamicFieldId.length)==dynamicFieldId) {
		
					field_required = true;

				} // end if
			
			}else{

				if(field_id==arrWeblineForm[weblineFormActivated]['required'][j]) {
		
					field_required = true;

				} // end if

			} // end if
	
		} // end for

	} // end if

	if(arrWeblineForm[weblineFormActivated]['unique'].length>0) {

		for(var j=0; j<arrWeblineForm[weblineFormActivated]['unique'].length; j++) {
		
			var arrUnique = arrWeblineForm[weblineFormActivated]['unique'][j].split("|");

			if(field_id==arrUnique[0]) {
		
				field_unique = arrUnique[1];

			} // end if
	
		} // end for

	} // end if

	if(arrWeblineForm[weblineFormActivated]['search'].length>0) {

		for(var j=0; j<arrWeblineForm[weblineFormActivated]['search'].length; j++) {
		
			var arrSearch = arrWeblineForm[weblineFormActivated]['search'][j].split("|");

			if(field_id==arrSearch[0]) {
		
				field_search = arrSearch[1];

			} // end if
	
		} // end for

	} // end if

	if(arrWeblineForm[weblineFormActivated]['exists'].length>0) {

		for(var j=0; j<arrWeblineForm[weblineFormActivated]['exists'].length; j++) {
		
			var arrExists = arrWeblineForm[weblineFormActivated]['exists'][j].split("|");

			if(field_id==arrExists[0]) {
		
				field_exists = arrExists[1];


			} // end if
	
		} // end for

	} // end if

	if(arrWeblineForm[weblineFormActivated]['equals'].length>0) {

		for(var j=0; j<arrWeblineForm[weblineFormActivated]['equals'].length; j++) {
		field_id
			var arrEquals = arrWeblineForm[weblineFormActivated]['equals'][j].split("|");

			if(field_id==arrEquals[0]) {
		
				field_equals = arrEquals[1];

			} // end if
	
		} // end for

	} // end if

	if(arrWeblineForm[weblineFormActivated]['depends'].length>0) {

		for(var j=0; j<arrWeblineForm[weblineFormActivated]['depends'].length; j++) {
		
			var arrDepends = arrWeblineForm[weblineFormActivated]['depends'][j].split("|");

			if(field_id==arrDepends[0]) {
			
				// Shift the first element off the array and join the rest back together with |
				
				arrDepends.shift();
		
				field_depends = arrDepends.join("|");

			}else if(document.getElementById(field_id).type=="radio") {
			
				// Also check if this is a radio button (same name, diferent ids)
		
				var arrFieldId = field_id.split("_");				
				arrFieldId.pop();		
				real_field_id = arrFieldId.join("_");

				if(real_field_id==arrDepends[0]) {
			
					// Shift the first element off the array and join the rest back together with |
				
					arrDepends.shift();
		
					field_depends = arrDepends.join("|");

				} // end if
			
			} // end if
	
		} // end for

	} // end if
	
	// Check if we have validation functions defined in the PHP module

	if(arrWeblineForm[weblineFormActivated]['validations'].length>0) {

		for(var j=0; j<arrWeblineForm[weblineFormActivated]['validations'].length; j++) {
		
			var arrValidations = arrWeblineForm[weblineFormActivated]['validations'][j].split("|");

			if(field_id==arrValidations[0]) {
		
				field_validations = arrValidations[1];

			} // end if
	
		} // end for

	} // end if
	
	// Check if we have groups defined in the PHP module

	if(arrWeblineForm[weblineFormActivated]['groups'].length>0) {

		for(var j=0; j<arrWeblineForm[weblineFormActivated]['groups'].length; j++) {
		
			var arrGroups = arrWeblineForm[weblineFormActivated]['groups'][j].split("|");

			if(field_id==arrGroups[0]) {
		
				field_group = arrGroups[1];

			} // end if
	
		} // end for

	} // end if

	weblineFormDebugConsole("[" + field_id + "] weblineFormGetFieldSettings: required=" + field_required + ", unique=" + field_unique + ", exists=" + field_exists + ", equals=" + field_equals + ", depends=" + field_depends + ", validations=" + field_validations + ", group=" + field_group + ", search=" + field_search,3);
	
	arrSettings = [field_id,field_required,field_unique,field_exists,field_equals,field_depends,field_validations,field_group,field_search];
	
	return arrSettings;

} // end function

/**
 * Validate a single field
 * 
 * @param string ID of the field you want to check
 * @param boolean Is this field required or not
 * @param false|string False in case disabled, the module uri in case enabled (like /staff/resource/employee/unique)
 * @param false|string False in case disabled, the module uri in case enabled (like /staff/resource/employee/exists)
 * @param false|string False in case disabled, the ID of the field it should match if enabled
 * @param false|string False in case disabled, the ID of the field it should depend on if enabled
 * @param false|string False in case disabled, comma seperated string of functions if enabled
 * @param string Id of the corresponding group. Leave empty when no group
 * @access private
 * @return boolean
 * @uses weblineFormGetValue()
 * @uses weblineFormValidateFieldOriginal()
 * @uses weblineFormValidateFieldChanged()
 * @uses weblineFormValidateFieldFunction()
 * @uses weblineFormValidateFieldUnique()
 * @uses weblineFormValidateFieldExists()
 * @uses weblineFormValidateFieldEquals()
 * @uses weblineFormToggleFieldDepends()
 * @uses weblineFormAddListener()
 */
function weblineFormValidateField(fieldId,fieldRequired,fieldUnique,fieldExists,fieldEquals,fieldDepends,fieldValidations,fieldGroup) {

	weblineFormDebugConsole("[" + fieldId + "] weblineFormValidateField: Start validation",2);
	
	// Get the object of the field

	var objField = document.getElementById(fieldId);
	
	// Check if field is dependent or not to another field
	
	if(fieldDepends!=false) {

		weblineFormToggleFieldDepends(fieldId,fieldDepends);
		
	} // end if
	
	// return true if fieldDepends is enabled and the field is hidden
	
	if(fieldDepends!=false && objField.style.display=="none") {
	
		return true;

	} // end if
	
	// Get the current value of the field
	
	var valField = weblineFormGetValue(objField);
	
	// Check if we have set the original value after the initial page load. If not, set the current value as the original.
	
	weblineFormValidateFieldOriginal(fieldId,valField);
	
	// Initialize the messages
		
	showMsg("invalid_" + fieldId,"init");
	showMsg("unique_" + fieldId,"init");
	showMsg("exists_" + fieldId,"init");
	showMsg("equals_" + fieldId,"init");
	
	// Set global validation to OK
	
	var validationGlobal = true;
	
	// Check if this field belongs to a group, and if the group is not hidden. If the group is hidden, don't proceed further for this field and leave as OK
	
	if(fieldGroup!="") {
	
		weblineFormDebugConsole("[" + fieldId + "] weblineFormValidateField: Group found: " + fieldGroup + ". Is it hidden? Should we validate this field?",5);
	
		if(document.getElementById(fieldGroup)) {
	
			if(document.getElementById(fieldGroup).style.display=="none") {
		
				return true;

			} // end if

		} // end if

	} // end if
				
	// Set all sub-validations to false
	
	var validationFunction = false;
	var validationUnique = false;
	var validationExists = false;
	var validationEquals = false;
	
	// See if the value is empty and/or unchanged
	
	var valueChanged = weblineFormValidateFieldChanged(fieldId,valField);
	var valueEmpty = true;
	
	if(valField!="") {
	
		valueEmpty = false;
		
	} // end if
	
	// Start checking stuff
	
	if(valueChanged) {
	
		if(!valueEmpty) {

			// The value of this field has changed and it is not empty, so we need to start validations
			
			weblineFormDebugConsole("[" + fieldId + "] weblineFormValidateField: field value changed since the last validation, starting new validation",4);
		
			// Check for user-defined functions to validate the value of the field
		
			var validationFunction = weblineFormValidateFieldFunction(fieldId,valField);

			if(!validationFunction) {
						
				validationGlobal = false;
		
			} // end if
				
			// Validation Unique
		
			if(fieldUnique!=false && arrWeblineFormOriginalValues[fieldId]!=valField) {
				
				validationUnique = weblineFormValidateFieldUnique(fieldId,valField,fieldUnique);

				if(!validationUnique) {
						
					validationGlobal = false;
		
				} // end if
			
			}else{
			
				validationUnique = true;
			
			} // end if
				
			// Validation Exists
		
			if(fieldExists!=false && arrWeblineFormOriginalValues[fieldId]!=valField) {
				
				validationExists = weblineFormValidateFieldExists(fieldId,valField,fieldExists);

				if(!validationExists) {
						
					validationGlobal = false;
		
				} // end if
			
			}else{
			
				validationExists = true;
			
			} // end if
	
		}else{
	
			if(fieldRequired) {
			
				// The value of this field is empty and unchanged, but it is required so INVALID
			
				weblineFormDebugConsole("[" + fieldId + "] weblineFormValidateField: field is required but empty so INVALID",4);
						
				validationGlobal = false;
				
			}else{
		
				showMsg("invalid_" + fieldId,"hide");
				showMsg("unique_" + fieldId,"hide");
				showMsg("exists_" + fieldId,"hide");
				showMsg("equals_" + fieldId,"hide");
			
			} // end if
			
		} // end if
						
		// Save results for the next check

		arrWeblineFormLastValues[fieldId] = valField;		
		arrWeblineFormLastTests[fieldId] = validationGlobal;
	
	}else{
	
		// This field is already validated and did not change so use the last result again
			
		weblineFormDebugConsole("[" + fieldId + "] weblineFormValidateField: field value did not change since the last validation",4);
		
		validationGlobal = arrWeblineFormLastTests[fieldId];
	
	} // end if
				
	// Validation Equals

	if(fieldEquals!=false) {
		
		validationEquals = weblineFormValidateFieldEquals(fieldId,valField,fieldEquals);

		if(!validationEquals) {
				
			validationGlobal = false;

		} // end if
	
	}else{
	
		validationEquals = true;
	
	} // end if
	
	// Execute trigger weblineFormTriggerValidated
	
	weblineFormTrigger("validated",fieldId,validationGlobal);
				
	// Process all the validations and change the field background color and show messages according to the results
	
	if(validationGlobal && valField!="") {
		
		objField.style.backgroundColor = weblineFormColorValid;
			
	}else if(validationGlobal) {
		
		objField.style.backgroundColor = weblineFormColorNormal;
	
	}else{
		
		objField.style.backgroundColor = weblineFormColorInvalid;
	
	} // end if
	
	// Add a listener to this field. This function will only set a listener if it does not exists yet.
	
	weblineFormAddListener(fieldId);
	
	// Return the final result for this field
	
	return validationGlobal;

} // end function

/**
 * Store the original values if not yet stored.
 *
 * @param string ID of the field which value should be stored
 * @param string Value of the field
 * @access private
 * @return void
 */
function weblineFormValidateFieldOriginal(fieldId,valField) {
	
	if(String(arrWeblineFormOriginalValues[fieldId])=="undefined") {
	
		if(valField=="") {
	
			arrWeblineFormOriginalValues[fieldId] = "";
		
		}else{
	
			arrWeblineFormOriginalValues[fieldId] = valField;
			
		} // end if
	
		weblineFormDebugConsole("[" + fieldId + "] weblineFormValidateFieldOriginal: Original value set to '" + arrWeblineFormOriginalValues[fieldId] + "'",4);
	
	} // end if

} // end function

/**
 * Has the value of this field changed since the last check we stored?
 *
 * @param string ID of the field that should be checked
 * @param string Value of the field
 * @access private
 * @return boolean
 */
function weblineFormValidateFieldChanged(fieldId,valField) {

	weblineFormDebugConsole("[" + fieldId + "] weblineFormValidateFieldChanged: Check if the value of the field has changed",5);
		
	var fieldchanged = false;

	if(!arrWeblineFormLastValues[fieldId] || arrWeblineFormLastValues[fieldId]!=valField) {
	
		fieldchanged = true;
	
	} // end if
	
	//weblineDebugConsole("[" + fieldId + "] weblineFormValidateFieldChanged: Result = "+fieldchanged,5);
		
	return fieldchanged;

} // end function

/**
 * Validate a fields value through user-defined functions
 *
 * @param string ID of the field that should be checked through the user-defined function
 * @param string Value of the field
 * @access private
 * @return boolean
 * @uses weblineFormGetFunctionName()
 * @uses weblineFormValidateFieldFunctionCheck()
 */
function weblineFormValidateFieldFunction(fieldId,valField) {
	
	weblineFormDebugConsole("[" + fieldId + "] weblineFormValidateFieldFunction: Validate the value through external functions",5);
		
	// Get the function name to call for validation of this fields value

	var funcname = weblineFormGetFunctionName(fieldId);
	var arguments = "";
	var result = false;
	
	// Check if this funcname represents multiple validations
	
	if(funcname.indexOf("/")!=-1) {
	
		arrFunctions = funcname.split("/");
		result = true;
		
		for(var i=0; i<arrFunctions.length; i++) {
		
			var tempResult = weblineFormValidateFieldFunctionCheck(fieldId,valField,arrFunctions[i]);
			
			if(!tempResult) {
			
				result = false;
				
			} // end if
		
		} // end for
	
	}else{
	
		result = weblineFormValidateFieldFunctionCheck(fieldId,valField,funcname);
		
	} // end if
	
	// Show/hide message

	if(result) {

		showMsg("invalid_" + fieldId,"hide");
	
	}else{

		showMsg("invalid_" + fieldId,"show");

	} // end if
	
	// Return the result
	
	return result;

} // end function

/**
 * This function will check a single javascript function. This is called from weblineFormValidateFieldFunction for each validation function specified.
 *
 * @param string ID of the field you want to check
 * @param string Value of the field you want to check
 * @param string Name of the function you want to check against
 * @access private
 * @return boolean
 */
function weblineFormValidateFieldFunctionCheck(fieldId,valField,funcname) {

	var arguments = "";
	
	// Check if we have arguments
	
	if(funcname.indexOf("(")!=-1) {
	
		var arrFuncname = funcname.split("(");
		
		funcname = arrFuncname[0];
		arguments = arrFuncname[1].substring(0,(arrFuncname[1].length - 1));
	
	} // end if

	// Check if this function exists

	eval("if(typeof " + funcname + " == 'function') { var funcexists=true; }else{ funcexists=false; }");			
	eval("if(typeof isValid == 'function') { var funcIsValidExists=true; }else{ funcIsValidExists=false; }");

	// Prepare the command to eval

	var command_prefix = "var result = ";
	var command_suffix = ";";
	var command = "";

	if(!funcexists) {

		if(!funcIsValidExists) {
		
			if(arguments!="") {
				
				command = "weblineValidateDefault(valField," + arguments + ")";
				
			}else{

				command = "weblineValidateDefault(valField)";
				
			} // end if
		
		}else{
		
			/*** What is this ??????? ***/
		
			if(arguments!="") {

				command = "isValid(fieldId,valField," + arguments + ")";
				
			}else{

				command = "isValid(fieldId,valField)";
				
			} // end if

		} // end if					

	}else{
		
		if(arguments!="") {
		
			//weblineDebugConsole(/^\d$/gi.test(arguments));
			
			var arrArguments = arguments.split(/,/g);
			
			for(var i=0;i<arrArguments.length;i++) {
				
				var arg = arrArguments[i];
				
				if(!arg.match(/^\d$/g)) {
			
					arrArguments[i] = "'"+arg+"'";
			
				} // end if		
				
			} // end for
			
			arguments = arrArguments.join(",");

			command = funcname + "(valField," + arguments + ")";
		
		}else{

			command = funcname + "(valField)";

		} // end if		

	} // end if

	weblineFormDebugConsole("[" + fieldId + "] weblineFormValidateFieldFunctionCheck: Command to execute for validation: " + command,5);

	// Execute the command and retrieve the result of the validation
				
	eval(command_prefix + command + command_suffix);
	
	return result;

} // end function

/**
 * Validate a field through AJAX to check if it is unique
 *
 * @param string ID of the field that should be checked through the ajax module
 * @param string Value of the field
 * @param string URL of the AJAX module to call
 * @access private
 * @return boolean
 * @uses weblineFormValidateFieldAjax()
 */
function weblineFormValidateFieldUnique(fieldId,valField,fieldAjaxUrl) {

	weblineFormValidateFieldAjax(fieldId,valField,fieldAjaxUrl);
				
	weblineFormDebugConsole("[" + fieldId + "] weblineFormValidateFieldUnique: " + arrWeblineFormLastAjaxTests[fieldId],5);
	
	if(arrWeblineFormLastAjaxTests[fieldId]) {

		showMsg("unique_" + fieldId,"hide");

	}else{

		showMsg("unique_" + fieldId,"show");

	} // end if	
	
	return arrWeblineFormLastAjaxTests[fieldId];

} // end function

/**
 * Validate a field through AJAX to check if it is existing
 *
 * @param string ID of the field that should be checked through the ajax module
 * @param string Value of the field
 * @param string URL of the AJAX module to call
 * @access private
 * @return boolean
 * @uses weblineFormValidateFieldAjax()
 */
function weblineFormValidateFieldExists(fieldId,valField,fieldAjaxUrl) {

	weblineFormValidateFieldAjax(fieldId,valField,fieldAjaxUrl);
				
	weblineFormDebugConsole("[" + fieldId + "] weblineFormValidateFieldExists: " + arrWeblineFormLastAjaxTests[fieldId],5);

	if(arrWeblineFormLastAjaxTests[fieldId]) {

		showMsg("exists_" + fieldId,"hide");

	}else{

		showMsg("exists_" + fieldId,"show");

	} // end if	
	
	return arrWeblineFormLastAjaxTests[fieldId];

} // end function

/**
 * Performs the AJAX request for the unique validation, and set a global variable with the result
 *
 * @param string ID of the field that should be checked through the ajax module
 * @param string Value of the field
 * @param string URL of the AJAX module to call
 * @access private
 * @return boolean
 */
function weblineFormValidateFieldAjax(fieldId,valField,fieldAjaxUrl) {
	
	// Set loading icon
	
	if(document.getElementById("weblineFormFieldAjaxLoading")==null) {
			
		var loadingEl = document.createElement("img");
	
		loadingEl.setAttribute("src","/includes/framework/images/notice/loading.gif");
		loadingEl.setAttribute("id","weblineFormFieldAjaxLoading");
		loadingEl.setAttribute("width","18");
		loadingEl.setAttribute("height","18");
		loadingEl.setAttribute("style","padding:0px; padding-left:4px; width:18px; height:18px; display:; margin:0px;");
		loadingEl.setAttribute("border","0");
	
		document.getElementById(fieldId).parentNode.appendChild(loadingEl);
	
	} // end if
	
	// Perform AJAX request
	
	arrWeblineFormLastAjaxTests[fieldId] = false;

	var parse_url = fieldAjaxUrl + "?" + fieldId + "=" + valField;

	http = getHttp();	
	http.abort();	
	http.open("GET",parse_url,false);					
	http.send(null);
	
	if(http.responseText=="true" || http.responseText=="1") {
		
		arrWeblineFormLastAjaxTests[fieldId] = true;
		
	}else{
		
		arrWeblineFormLastAjaxTests[fieldId] = false;
		
	} // end if
	
	// Remove loading icon
	
	var loadingIcon = document.getElementById("weblineFormFieldAjaxLoading");	
	loadingIcon.parentNode.removeChild(loadingIcon);

} // end function

/**
 * Check if this fields is equal to another field
 *
 * @param string ID of the field that should be checked
 * @param string Value of the field
 * @param string ID of the field it should be equal to
 * @access private
 * @return boolean
 */
function weblineFormValidateFieldEquals(fieldId,valField,fieldEquals) {

	var testField = true;
	showMsg("equals_" + fieldId,"hide");
	
	var objCurrentField = document.getElementById(fieldId);
	var objMathingField = document.getElementById(fieldEquals);
	
	if(objMathingField.value!="") {

		weblineFormDebugConsole("[" + fieldId + "] weblineFormValidateFieldEquals: Fields should equal: " + fieldId + "==" + fieldEquals,5);
	
		if(objCurrentField.value!=objMathingField.value) {

			testField = false;
			showMsg("equals_" + fieldId,"show");

		} // end if	

	} // end if	
	
	return testField;

} // end function

/**
 * Check if this fields is dependent to another field
 *
 * @param string ID of the field that should be checked
 * @param string ID of the field it should be dependent of
 * @access private
 * @return void
 */
function weblineFormToggleFieldDepends(fieldId,fieldDepends) {

	var filter = /[|]/;
	var fieldDependsCondition = false;
	var fieldDependsResult = false;

	if(filter.test(fieldDepends)) {
	
		var arrDepends = fieldDepends.split("|");
		
		fieldDepends = arrDepends[0];
		fieldDependsCondition = arrDepends[1];
		
		if(arrDepends[2]=="true") {
		
			fieldDependsResult = true;
		
		} // end if
	
	} // end if
		
	weblineFormDebugConsole("[" + fieldId + "] weblineFormToggleFieldDepends: " + fieldId + " dependent of " + fieldDepends + " with condition " + fieldDependsCondition + " with result " + fieldDependsResult,2);
	
	var objCurrentField = document.getElementById(fieldId);
	var objDependsField = document.getElementById(fieldDepends);
	if(!objDependsField) var objDependsField = document.getElementById(fieldDepends+"_"+fieldDependsCondition);

	var currentState = objCurrentField.style.display;
	var newState = false;
	
	// Get the value for the dependent field
	
	var dependentValue = weblineFormGetValue(objDependsField);

	// Check if the dependent field is a checkbox or radio
	
	if(objDependsField.type=="checkbox" || objDependsField.type=="radio") {
	
		if(!objDependsField.checked) {
		
			dependentValue = "";
			
		} // end if
	
	} // end if
	
	// Check if there is a condition for this dependency
	
	if(fieldDependsCondition!=false) {
	
		weblineFormDebugConsole(fieldDependsResult+" "+dependentValue+"=="+fieldDependsCondition);
	
		if(fieldDependsResult==true && dependentValue==fieldDependsCondition) {
	
			newState = "";
		
		}else if(fieldDependsResult==false && dependentValue!=fieldDependsCondition) {
	
			newState = "";
		
		}else{
	
			newState = "none";
		
		} // end if
	
	}else{
	
		if(dependentValue!="") {
	
			newState = "";
		
		}else{
	
			newState = "none";
		
		} // end if
		
	} // end if
	
	if(newState!=currentState) {
		
		objCurrentField.style.display = newState;
				
		if(objCurrentField.type!="radio") {
		
			getParentTag(objCurrentField,"TR").style.display = newState;
		
		}else{
		
			getParentTag(objCurrentField,"TR",2).style.display = newState;
		
		} // end if
		
		weblineFormValidate();
		
	} // end if

} // end function

function getParentTag(obj,tag,quantity) {

	if(typeof quantity == "undefined")quantity = 1;
	
	var currLevel = obj;
	var hits = 0;
	
	while(hits<quantity && currLevel.tagName != "BODY") {
	
		var currLevel = currLevel.parentNode;
		
		if(currLevel.tagName == tag) {
		
			hits++;
		
		} // end if
	
	} // end while
	
	return currLevel;

} // end function

/**
 * Add an event handler/listener to a field but only when it has not been set before
 *
 * @param string ID of the field
 * @access private
 * @return void
 * @uses weblineFormPropertyCheck()
 */
function weblineFormAddListener(fieldId) {
			
	// First check if the event handler/listener is already set, if so we need to skip this function
	
	var handlerExists = true;
	
	if(arrWeblineFormListeners.length==0) {
	
		handlerExists = false;
		
	}else{
	
		if(arrWeblineFormListeners[fieldId]==undefined) {
		
			handlerExists = false;
		
		} // end if
	
	} // end if
	
	if(!handlerExists) {
	
		if(BrowserDetect.browser=="Explorer") {
		
			// Debug information

			weblineFormDebugConsole("[" + fieldId + "] weblineFormAddListener: Add IE listener",4);

			// Register the event handler/listener

			document.getElementById(fieldId).onpropertychange = weblineFormPropertyCheck;
			
			// Add the field to the array so we know the event handler is set
		
			arrWeblineFormListeners[arrWeblineFormListeners.length] = fieldId;
		
		}else{
		
			// Debug information

			weblineFormDebugConsole("[" + fieldId + "] weblineFormAddListener: Add Firefox listener",4);

			// Register the event handler/listener

			document.getElementById(fieldId).addEventListener("keyup",weblineFormCall,false);
			document.getElementById(fieldId).addEventListener("change",weblineFormCall,false);
			document.getElementById(fieldId).addEventListener("focus",weblineFormCall,false);
			
			// Add the field to the array so we know the event handler is set
		
			arrWeblineFormListeners[arrWeblineFormListeners.length] = fieldId;
			
		} // end if
				
	} // end if

} // end function

/**
 * Check the property of a field when validating in IE
 *
 * @access private
 * @return void
 * @uses weblineFormCall()
 */
function weblineFormPropertyCheck() {

	var prop = event.propertyName;

	if(prop=="value" || prop=="checked") {

		var name = window.event.srcElement.id

		weblineFormCall(name);

	} // end if

} // end function

/**
 * Wrapper function for debugging to console
 *
 * @param string Debug message as a string
 * @param int Level of debugging. Defaults to 0
 * @access private
 * @return void
 * @uses weblineFormDebugConsole()
 */
function weblineFormDebugConsole(debugMsg,debugLevel) {

	if(weblineFormDebug!==false) {
	
		if(debugLevel==undefined) {
		
			debugLevel = 0;
		
		} // end if
		
		debugPrefix = new Array(debugLevel+1).join("  ");
	
		if(weblineFormDebug>=debugLevel) {

			weblineDebugConsole(debugPrefix+debugMsg);
			
		} // end if

	} // end if

} // end function

/**
 * Wrapper fucntion for debugging in groups to console
 *
 * @param string groupName name to display
 * @param bool open open on load?
 * @return void
 */
function weblineFormDebugGroup(groupName,open) {

	if(typeof open == "undefined")open = false;

	if(weblineFormDebug!==false) {
	
		if(typeof debugLevel == "undefined") {
		
			debugLevel = 0;
		
		} // end if
			
		if(weblineFormDebug>=debugLevel) {
			
			if(open) {
			
				WeblineConsole.group(groupName);
			
			}else{
			
				WeblineConsole.groupCollapsed(groupName);
				
			} // end if
			
		} // end if

	} // end if	

} // end function

/**
 * Toggle button on or off
 *
 * @param boolean Should we enable the button or not. If you do not pass this argument, it will default to false.
 * @access private
 */
function weblineFormToggleButton(enableButton) {
	
	// Check if argument is set, if not, default to false.
	
	if(String(enableButton)=="undefined") {

		enableButton = false;
		
	} // end if
	
	// Some debugging

	if(enableButton) {

		weblineFormDebugConsole("[" + arrWeblineForm[weblineFormActivated]['formid'] + "] weblineFormToggleButton: Enable the button for this form",1);
		
	}else{

		weblineFormDebugConsole("[" + arrWeblineForm[weblineFormActivated]['formid'] + "] weblineFormToggleButton: Disable the button for this form",1);
		
	} // end if
	
	// Set button and icons
	
	var buttonId = arrWeblineForm[weblineFormActivated]['button'];
	var buttonIconActive = arrWeblineForm[weblineFormActivated]['icon_ok'];
	var buttonIconInactive = arrWeblineForm[weblineFormActivated]['icon_nok'];
	
	/*
	
	// Get the button

	var objFormButton = document.getElementById(buttonId);
	
	// Enable or disable the button

	if(enableButton) {
	
		// Change the icon
	
		objFormButton.style.backgroundImage = "url(" + buttonIconActive + ")";
		
		// Load the previously stored link
		
		href = arrWeblineForm[weblineFormActivated]['href'];

	}else{
	
		// Change the icon
	
		objFormButton.style.backgroundImage = "url(" + buttonIconInactive + ")";
		
		// Check if link has already been disabled
		
		if(objFormButton.href!="javascript:void(0);") {
		
			// Store the link in case we need to re-activate the button
		
			arrWeblineForm[weblineFormActivated]['href'] = objFormButton.href;
			
			// Disable the link of the button
			
			objFormButton.href = "javascript:void(0);";
			
		} // end if

	} // end if
	
	*/
	
	// Search for all the other buttons on the page
	
	for(var i=0;i<6;i++) {
	
		if(document.getElementById(buttonId+i) || (i==0 && document.getElementById(buttonId))) {
		
			var newButtonId = buttonId+i;
			
			if(i==0) {
			
				newButtonId = buttonId;

			} // end if
	
			// Enable or disable the button

			if(enableButton) {
	
				icon = buttonIconActive;		
				href = arrWeblineForm[weblineFormActivated]['href'];
					
				weblineFormToggleButtonEnable(newButtonId,icon,href);

			}else{
	
				icon = buttonIconInactive;
				
				var objFormButton = document.getElementById(buttonId);
		
				if(objFormButton.href!="javascript:void(0);") {
		
					arrWeblineForm[weblineFormActivated]['href'] = objFormButton.href;
					
					weblineFormToggleButtonDisable(newButtonId,icon);
			
				} // end if

			} // end if
		
		} // end if
	
	} // end for
	
} // end function

/**
 * Enable the form button
 *
 * @access private
 * @param string ID of the button
 * @param string full-path to the icon
 * @param string href of the link
 * @return void
 */
function weblineFormToggleButtonEnable(buttonId,icon,href) {
	
	// Get the button

	var objFormButton = document.getElementById(buttonId);
	
	// Change the icon

	objFormButton.style.backgroundImage = "url(" + icon + ")";
	
	// Load the previously stored link
	
	objFormButton.href = href;

} // end function

/**
 * Disable the form button
 *
 * @access private
 * @param string ID of the button
 * @param string full-path to the icon
 * @return void
 */
function weblineFormToggleButtonDisable(buttonId,icon) {
	
	// Get the button

	var objFormButton = document.getElementById(buttonId);
	
	//WeblineConsole.log(objFormButton);
	
	// Change the icon

	objFormButton.style.backgroundImage = "url(" + icon + ")";
	
	// Check if link has already been disabled
	
	if(objFormButton.href!="javascript:void(0);") {
		
		// Disable the link of the button
		
		objFormButton.href = "javascript:void(0);";
		
	} // end if

} // end function

/**
 * Get the value for a field
 *
 * @param object objField The object for the field
 * @access private
 * @return string value
 * @uses weblineFormGetValueDropdown()
 * @uses weblineFormGetValueRadio()
 */
function weblineFormGetValue(objField) {

	weblineFormDebugConsole("[" + objField.id + "] weblineFormGetValue: Get the value for this field",4);
	
	// Get the current value of the field
	
	var valField = objField.value;
		
	// check if we are dealing with a dropdown. If so we need to fetch the value from the selected entry in the dropdown box

	if(objField.options) {
			
		valField = weblineFormGetValueDropdown(objField);
	
	} // end if
	
	// check if we are dealing with radio buttons. If so we need to fetch the value from the checked entry

	if(objField.type=="radio") {
	
		valField = weblineFormGetValueRadio(objField);
	
	} // end if
	
	return valField;

} // end function

/**
 * Get the value of a dropdown box
 *
 * @param object objField The object for the field
 * @access private
 * @return string value
 */
function weblineFormGetValueDropdown(objField) {
				
	var valField = "";

	if(objField.selectedIndex >= 0) {
	
		var x = objField.selectedIndex;
		
		if(objField.options[x].text!="not_used" && objField.options[x].text!="") {
		
			valField = objField.options[x].value;
		
		} // end if
		
	} // end if

	weblineFormDebugConsole("[" + objField.id + "] weblineFormGetValueDropdown: This field is a dropdown. Fetched the value as '" + valField + "'",4);
	
	return valField;

} // end function

/**
 * Get the value of a radio button
 *
 * @param object objField The object for the field
 * @access private
 * @return string value
 */
function weblineFormGetValueRadio(objField) {
	
	var valField = "";

	if(!arrWeblineFormValidateRadios[objField.name]) {
	
		arrWeblineFormValidateRadios[objField.name] = document.getElementsByName(objField.name);
		
	} // end if
	
	for(var i=0;i<arrWeblineFormValidateRadios[objField.name].length;i++) {
	
		var radio = arrWeblineFormValidateRadios[objField.name][i];
		
		if(radio.checked) {
			
			valField = radio.value;
	
		} // end if
		
		if(valField!="")continue;
		
	} // end for
	
	weblineFormDebugConsole("[" + objField.id + "] weblineFormGetValueRadio: This field is a radio button. Fetched the value as '" + valField + "'",4);

	return valField;

} // end function

/**
 * Get the function names for validation
 *
 * @param string ID of the field
 * @access private
 * @return string The name of the function to call
 */
function weblineFormGetFunctionName(fieldId) {

	funcname = "undefined";
	
	// Check to see if there are validations defined in the PHP module

	var arrFunctions = arrWeblineForm[weblineFormActivated]['validations'];
	
	for(var i=0; i<arrFunctions.length; i++) {
				
		var arrFunction = arrWeblineForm[weblineFormActivated]['validations'][i].split("|");

		if(fieldId==arrFunction[0]) {

			funcname = arrFunction[1];

		} // end if
	
	} // end for
	
	/*
	
	// No PHP validation defined, try to determine from fieldId
	
	if(String(funcname)=="undefined") {
	
		weblineFormDebugConsole("[" + fieldId + "] weblineFormGetFunctionName: Trying to figure out the function we should call to validate this fields value");
		
		var funcname = "weblineValidate"+fieldId.charAt(0).toUpperCase()+fieldId.substr(1).toLowerCase();
	
		// Remove trailing _X where X represents a number. This is for dealing with multi-edit forms.
	
		var arrFuncname = funcname.split("_");
		var lastFuncnameElement = arrFuncname[arrFuncname.length-1];
	
		if(isValidInt(lastFuncnameElement)) {
		
			var newfuncname = "";
		
			for(var i=0; i<(arrFuncname.length-1); i++) {
		
				newfuncname = newfuncname + arrFuncname[i];
		
			} // end for
		
			funcname = newfuncname
		
		} // end if
	
	} // end if
	
	*/
	
	// No PHP validation defined, use default
	
	if(String(funcname)=="undefined") {
	
		funcname = "weblineValidateDefault";
		
	} // end if
	
	weblineFormDebugConsole("[" + fieldId + "] weblineFormGetFunctionName: function is called '" + funcname + "'",6);
	
	return funcname;

} // end function

/**
 * Inset a new group of fields. In case the first group is present but hidden, we will show it. If not, we will add a new group of elements below.
 *
 * @param string ID of the group of fields. Most likely the ID of the parent row of these fields.
 * @param object objAction You should add 'this' as the second argument in your template so we can change the onchnage-command for this action.
 * @access public
 * @return void
 * @uses weblineFormGroupDuplicate()
 * @uses weblineFormValidate()
 */
function weblineFormGroupInsert(groupId,objAction) {
	
	// Get the group element
	
	var objGroup = document.getElementById(groupId);
	
	// check to see if it is hidden, if so just display the element, otherwise duplicate the element and add below

	if(objGroup.style.display=="none") {
		
		weblineFormDebugConsole("[" + groupId + "] weblineFormGroupInsert: We need to unhide this group",2);

		// Show element

		objGroup.style.display = "";
		
		// Remove the 'disabled' atribute from the fields
	
		var arrFields = weblineFormGroupGetFields(groupId);
	
		// Loop the array of fields and get the objects
	
		for(var i=0; i<arrFields.length; i++) {
		
			var objField = document.getElementById(arrFields[i][0]);
	
			objField.removeAttribute("disabled");
	
		} // end for		

	}else{
		
		weblineFormDebugConsole("[" + groupId + "] weblineFormGroupInsert: We need to duplicate this group",2);
		
		// Duplicate element

		weblineFormGroupDuplicate(groupId,objAction);

	} // end if
	
	// Validate the form again
	
	weblineFormValidate();

} // end function

/**
 * Update the button of a group which adds/duplicates groups. It will automatically find the correct button, no matter which group you pass.
 *
 * @param string ID of any group of fields for the button you want to update.
 * @access private
 * @return void
 * @uses weblineFormGroupGetLast()
 */
function weblineFormGroupUpdateAddButton(groupId) {
	
	weblineFormDebugConsole("[" + groupId + "] weblineFormGroupUpdateAddButton: Function called",2);
			
	// Find the last group present on the page
	
	var objLastGroup = weblineFormGroupGetLast(groupId);
	
	// Check that buttons have been defined
		
	if(arrWeblineForm[weblineFormActivated]['group_buttons'][groupId]!=undefined) {
	
		// Get the add action button stored in arrWeblineForm

		var buttonIdAdd = arrWeblineForm[weblineFormActivated]['group_buttons'][groupId];	
		var objButtonAdd = document.getElementById(buttonIdAdd);
		
		if(objLastGroup!=false) {

			var groupIdToDuplicate = objLastGroup.id;
	
		}else{

			var arrGroupId = groupId.split("_");	
			var groupIdToDuplicate = arrGroupId[0] + "_0";

		} // end if
		
		// check to see if it is different
		
		var newLocation = "weblineFormGroupInsert('" + groupIdToDuplicate + "',this);";
		
		if(objButtonAdd.getAttribute("onclick")!=newLocation) {

			objButtonAdd.setAttribute("onclick","weblineFormGroupInsert('" + groupIdToDuplicate + "',this);");
	
			weblineFormDebugConsole("[" + groupId + "] weblineFormGroupUpdateAddButton: Changed onclick for add button to weblineFormGroupInsert('" + groupIdToDuplicate + "',this);",2);
			
		} // end if
	
	} // end if

} // end function

/**
 * Remove an existing group of fields. In case of the first one (number 0), it will just hide it instead of removing.
 *
 * @param string ID of the group of fields. Most likely the ID of the parent row of these fields.
 * @param object objAction You should add 'this' as the second argument in your template so we can change the onchnage-command for this action.
 * @access public
 * @return void
 * @uses weblineFormGroupReset()
 * @uses weblineFormGroupUpdateAddButton()
 * @uses weblineFormValidate()
 */
function weblineFormGroupRemove(groupId,objAction) {
	
	// Get the group element
	
	var objGroup = document.getElementById(groupId);
	
	// Get the parent element
	
	var objParent = objGroup.parentNode;
	
	// Check if this is group number 0 (the first one), if so do not remove it but hide it
	
	var arrGroupId = groupId.split("_");
	
	if(arrGroupId.pop()=="0") {
		
		weblineFormDebugConsole("[" + groupId + "] weblineFormGroupRemove: We need to reset and hide this element",2);
	
		// Reset the fields for this group
	
		weblineFormGroupReset(objGroup.id,1);
	
		// Hide element
	
		objGroup.style.display = "none";
		
	}else{
		
		weblineFormDebugConsole("[" + groupId + "] weblineFormGroupRemove: We need to remove this element",2);
	
		// Remove element
	
		objParent.removeChild(objGroup);
	
		// Remove from the stored array
	
		var arrGroups = arrWeblineForm[weblineFormActivated]['groups'];
	
		for(var i=0; i<arrGroups.length; i++) {
	
			//weblineFormDebugConsole(arrWeblineForm[weblineFormActivated]['groups'][i]);
				
			var arrGroup = arrWeblineForm[weblineFormActivated]['groups'][i].split("|");

			if(groupId==arrGroup[1]) {
	
				//weblineFormDebugConsole(arrGroup[1]);

				arrWeblineForm[weblineFormActivated]['groups'][i] = "removed";

			} // end if
		
			//weblineFormDebugConsole(arrWeblineForm[weblineFormActivated]['groups'][i]);
	
		} // end for
	
	} // end if
	
	// Update the 'add' link
	
	weblineFormGroupUpdateAddButton(groupId);
	
	// Validate the form again
	
	weblineFormValidate();

} // end function

/**
 * Get the last stored group
 *
 * @param string ID of the group of fields
 * @access private
 * @return object
 */
function weblineFormGroupGetLast(groupId) {
	
	weblineFormDebugConsole("[" + groupId + "] weblineFormGroupGetLast: function called",3);
		
	// Split the ID to get the number

	var arrCurrentGroupId = groupId.split("_");
	
	// Start looping all stored groups and check if the numbers are higher. If so store the new highest number
	
	var maxGroup = 0;
	
	for(var i=0; i<arrWeblineForm[weblineFormActivated]['groups'].length; i++) {
	
		//weblineFormDebugConsole("test: "+arrWeblineForm[weblineFormActivated]['groups'][i]);
		
		if(arrWeblineForm[weblineFormActivated]['groups'][i]!="removed") {
	
			var arrGroup = arrWeblineForm[weblineFormActivated]['groups'][i].split("|");
			var objGroup = document.getElementById(arrGroup[1]);
			var arrGroupId = objGroup.id.split("_");
			var groupNumber = parseInt(arrGroupId[arrGroupId.length-1]);
			
			if(groupNumber>maxGroup) {
	
				maxGroup = groupNumber;
			
			} // end if
			
		} // end if
	
	} // end for
	
	//weblineDebugConsole(maxGroup);
	
	if(maxGroup==0) {
	
		return false;
		
	}else{
	
		// Return the object
	
		return document.getElementById(arrCurrentGroupId[0] + "_" + maxGroup);
		
	} // end if

} // end function

/**
 * Duplicate a group of fields and add below to the parent element.
 *
 * @param string ID of the group of fields. Most likely the ID of the parent row of these fields.
 * @param object objAction Object of the action element (button to add/duplicate a group)
 * @access private
 * @return void
 * @uses weblineFormGroupDuplicateRegister()
 */
function weblineFormGroupDuplicate(groupId,objAction) {
	
	weblineFormDebugConsole("[" + groupId + "] weblineFormGroupDuplicate: function called",2);
	
	// Get the group element
	
	var objGroup = document.getElementById(groupId);
	
	// Get the parent element
	
	var objParent = objGroup.parentNode;
	
	// Duplicate the group
	
	var objDuplicate = objGroup.cloneNode(true);

	// Append the group to the parent element

	objParent.appendChild(objDuplicate);
	
	// Renumber the new group of fields and register them
	
	weblineFormGroupDuplicateRegister(objDuplicate,objAction);

} // end function

/**
 * Renumber the fields of a group after it has been duplicated and register them
 *
 * @param object objDuplicate The new group object
 * @param object objAction Object of the action element (button to add/duplicate a group)
 * @access private
 * @return void
 * @uses weblineFormGroupGetFields()
 * @uses weblineFormGroupUpdateAddButton()
 * @uses weblineFormGroupResetField()
 */
function weblineFormGroupDuplicateRegister(objDuplicate,objAction) {
	
	weblineFormDebugConsole("[" + objDuplicate.id + "] weblineFormGroupDuplicateRegister: function called",3);
	
	// Get an array of fields
	
	var arrFields = weblineFormGroupGetFields(objDuplicate.id);
	
	// Update the groupId
		
	var currentGroupId = objDuplicate.id;
	var arrGroupId = currentGroupId.split("_");
	var lastNumber = Number(arrGroupId[arrGroupId.length-1]);
	
	arrGroupId[arrGroupId.length-1] = lastNumber + 1;	
		
	objDuplicate.id = arrGroupId.join("_");
	
	// Add the button to the stored array for this new groupId, so we know that the same button is used for this new group
	
	arrWeblineForm[weblineFormActivated]['group_buttons'][objDuplicate.id] = objAction.id;
	
	// Loop the array of fields and renumber as well as add the new fields to the settings array
	
	for(var i=0; i<arrFields.length; i++) {
	
		// Explode the id of each field and increase the last entry in the array
		
		var currentFieldId = arrFields[i][0];
		var arrFieldId = currentFieldId.split("_");
		var lastNumber = Number(arrFieldId[arrFieldId.length-1]);
		var newNumber = lastNumber + 1;
		
		arrFieldId[arrFieldId.length-1] = newNumber;
		
		// Implode again
		
		var newFieldId = arrFieldId.join("_");
	
		// Check if we have a default value for this field, so we can set it later on, and update the arrWeblineForm with the new fields default values
		
		var defaultValue = "";
		
		if(arrWeblineForm[weblineFormActivated]['default_values'][arrFields[i][0]]!=undefined) {
		
			weblineFormDebugConsole("[" + arrFields[i][0] + "] weblineFormGroupDuplicateRegister: Found default value for this field",4);
			
			defaultValue = arrWeblineForm[weblineFormActivated]['default_values'][arrFields[i][0]];
			
			// Update main array
			
			arrWeblineForm[weblineFormActivated]['default_values'][newFieldId] = defaultValue;
		
		} // end if
		
		// Keep an array of the new fields
		
		var arrNewFields = new Array();
		
		// Loop the duplicated element at least two levels deep, so we can update all fields. Get the field object
		
		//weblineFormDebugConsole("[" + objDuplicate.id + "] weblineFormGroupDuplicateRegister: Loop all elements two levels deep to find the field");
		
		for(var j=0; j<objDuplicate.childNodes.length; j++) {
		
			var objField = false;
			
			if(objDuplicate.childNodes[j].id) {
	
				if(objDuplicate.childNodes[j].id==currentFieldId) {
		
					//weblineFormDebugConsole("[" + objDuplicate.id + "] weblineFormGroupDuplicateRegister:    L1: " + objDuplicate.childNodes[j].id + "==" + currentFieldId);
		
					objField = objDuplicate.childNodes[j];
				
				} // end if
				
			}else{
		
				for(var k=0; k<objDuplicate.childNodes[j].childNodes.length; k++) {
		
					if(objDuplicate.childNodes[j].childNodes[k].id) {

						if(objDuplicate.childNodes[j].childNodes[k].id==currentFieldId) {
				
							//weblineFormDebugConsole("[" + objDuplicate.id + "] weblineFormGroupDuplicateRegister:    L2: " + objDuplicate.childNodes[j].childNodes[k].id + "==" + currentFieldId);
	
							objField = objDuplicate.childNodes[j].childNodes[k];
			
						} // end if
		
					} // end if
		
				} // end for
			
			} // end if
			
			// check if field is found
			
			if(objField!=false) {
		
				weblineFormDebugConsole("[" + objDuplicate.id + "] weblineFormGroupDuplicateRegister: Update the field with new ID " + newFieldId,4);
		
				// Update the ID
	
				objField.id = newFieldId;
				
				// Reset field
				
				weblineFormGroupResetField(newFieldId);
				
				// Insert default value if set
		
				if(defaultValue!="") {
		
					weblineFormDebugConsole("[" + newFieldId + "] weblineFormGroupDuplicateRegister: Setting the default value to '" + defaultValue + "'",4);
		
					objField.value = defaultValue;
					
				} // end if
				
				// Try to update the name
				
				var arrName = objField.name.split("[");				
				var lastNumber = Number(arrName[1].replace("]",""));		
				arrName[1] = lastNumber + 1;		
				arrName[1] = String(arrName[1] + "]");
				
				objField.name = arrName.join("[");
				
				// Check if there is a datepicker that needs updating
				
				var tableCell = objField.parentNode;
				
				if(tableCell.childNodes[2]!=undefined) {
				
					if(tableCell.childNodes[2].type=="button") {
				
						weblineFormDebugConsole("[" + objDuplicate.id + "] weblineFormGroupDuplicateRegister: We need to update the datepicker button next to the field",4);
						
						var objDatepicker = tableCell.childNodes[2];
				
						var arrDatepicker = objDatepicker.getAttribute("onclick").split("_");				
						var lastNumber = Number(arrDatepicker[arrDatepicker.length-1].match(/[0-9]+/gi));				
						
						arrDatepicker[arrDatepicker.length-1] = lastNumber + 1;	
						arrDatepicker[arrDatepicker.length-1] = String(arrDatepicker[arrDatepicker.length-1] + "')");

						objDatepicker.setAttribute("onclick",arrDatepicker.join("_"));
						
					} // end if
					
				} // end if
				
				// Check if there is a search form that needs updating
				
				var tableCell = objField.parentNode;
				
				if(tableCell.childNodes[3]!=undefined && tableCell.childNodes[5]!=undefined) {
				
					if(tableCell.childNodes[3].tagName=="A" && tableCell.childNodes[5].tagName=="DIV") {
					
						weblineFormDebugConsole("[" + objDuplicate.id + "] weblineFormGroupDuplicateRegister: We need to update the search form next to the field",4);
						
						var objSearchIcon = tableCell.childNodes[3];
						var objSearchDiv = tableCell.childNodes[5];
						var objSearchString = objSearchDiv.childNodes[1];
						var objSearchHide = objSearchString.childNodes[1];
						var objSearchResult = objSearchDiv.childNodes[3];
						
						// Update search icon
				
						var arrSearchIcon = objSearchIcon.getAttribute("onclick").split("_");				
						var lastNumber = Number(arrSearchIcon[arrSearchIcon.length-1].replace("');",""));		
						arrSearchIcon[arrSearchIcon.length-1] = lastNumber + 1;	
						arrSearchIcon[arrSearchIcon.length-1] = String(arrSearchIcon[arrSearchIcon.length-1] + "');");
				
						objSearchIcon.setAttribute("onclick",arrSearchIcon.join("_"));
						
						// Update search div
				
						var arrSearchDiv = objSearchDiv.getAttribute("id").split("_");				
						var lastNumber = Number(arrSearchDiv[arrSearchDiv.length-2]);		
						arrSearchDiv[arrSearchDiv.length-2] = lastNumber + 1;	
						arrSearchDiv[arrSearchDiv.length-2] = String(arrSearchDiv[arrSearchDiv.length-2]);
				
						objSearchDiv.setAttribute("id",arrSearchDiv.join("_"));
						
						// Update search string
				
						var arrSearchString = objSearchString.getAttribute("id").split("_");				
						var lastNumber = Number(arrSearchString[arrSearchString.length-2]);		
						arrSearchString[arrSearchString.length-2] = lastNumber + 1;	
						arrSearchString[arrSearchString.length-2] = String(arrSearchString[arrSearchString.length-2]);
				
						objSearchString.setAttribute("id",arrSearchString.join("_"));
						
						// Update search hide button
				
						var arrSearchHide = objSearchHide.getAttribute("onclick").split("_");				
						var lastNumber = Number(arrSearchHide[arrSearchHide.length-1].replace("');",""));		
						arrSearchHide[arrSearchHide.length-1] = lastNumber + 1;	
						arrSearchHide[arrSearchHide.length-1] = String(arrSearchHide[arrSearchHide.length-1] + "');");
				
						objSearchHide.setAttribute("onclick",arrSearchHide.join("_"));
						
						// Update search result
				
						var arrSearchResult = objSearchResult.getAttribute("id").split("_");				
						var lastNumber = Number(arrSearchResult[arrSearchResult.length-2]);		
						arrSearchResult[arrSearchResult.length-2] = lastNumber + 1;	
						arrSearchResult[arrSearchResult.length-2] = String(arrSearchResult[arrSearchResult.length-2]);
				
						objSearchResult.setAttribute("id",arrSearchResult.join("_"));

						// Find the search location
						
						var arrParentSettings = weblineFormGetFieldSettings(currentFieldId);
						var search_location = arrParentSettings[8];
						
						// Register the search form
						
						arrWeblineForm[weblineFormActivated]['search'][arrWeblineForm[weblineFormActivated]['search'].length] = newFieldId+"|"+search_location;
						
						// Initialize the search function
						
						weblineFormSearchInit(arrWeblineForm[weblineFormActivated]['formid']);
						
					} // end if
					
				} // end if
				
				// Add to the forms array with original settings
				
				/*
				field_id,field_required,field_unique,field_exists,field_equals,field_depends,field_validations,field_group
				*/
				
				if(arrFields[i][1]!=false) {
				
					arrWeblineForm[weblineFormActivated]['required'][arrWeblineForm[weblineFormActivated]['required'].length] = newFieldId;
					
				} // end if
				
				if(arrFields[i][2]!=false) {
				
					arrWeblineForm[weblineFormActivated]['unique'][arrWeblineForm[weblineFormActivated]['unique'].length] = newFieldId + "|" + arrFields[i][2];
					
				} // end if
				
				if(arrFields[i][3]!=false) {
				
					arrWeblineForm[weblineFormActivated]['exists'][arrWeblineForm[weblineFormActivated]['exists'].length] = newFieldId + "|" + arrFields[i][3];
					
				} // end if
				
				if(arrFields[i][4]!=false) {
				
					arrWeblineForm[weblineFormActivated]['equals'][arrWeblineForm[weblineFormActivated]['equals'].length] = newFieldId + "|" + arrFields[i][4];
					
				} // end if
				
				if(arrFields[i][5]!=false) {
				
					arrWeblineForm[weblineFormActivated]['depends'][arrWeblineForm[weblineFormActivated]['depends'].length] = newFieldId + "|" + arrFields[i][5];
					
				} // end if
				
				if(arrFields[i][6]!=false) {
				
					arrWeblineForm[weblineFormActivated]['validations'][arrWeblineForm[weblineFormActivated]['validations'].length] = newFieldId + "|" + arrFields[i][6];
					
				} // end if
				
				if(arrFields[i][7]!=false) {
				
					arrWeblineForm[weblineFormActivated]['groups'][arrWeblineForm[weblineFormActivated]['groups'].length] = newFieldId + "|" + objDuplicate.id;
					
				} // end if
			
			} // end if
			
		} // end for
	
	} // end for
	
	// Update the onclick command to add a new row
	
	weblineFormGroupUpdateAddButton(objDuplicate.id);
	
	//objAction.setAttribute("onclick","weblineFormGroupInsert('" + objDuplicate.id + "',this);");
	
	//weblineFormDebugConsole("[" + objDuplicate.id + "] weblineFormGroupDuplicateRegister: Changed onclick for add button to weblineFormGroupInsert('" + objDuplicate.id + "',this);");
	
	// Finally we need to search for the delete button and update that one as well
	
	var objButton = weblineFormGroupGetRemoveButton(objDuplicate);
		
	// check if button is found
		
	if(objButton!=false) {
	
		// Get the current command and find id of add button
		
		var currentCommand = objButton.getAttribute("onclick");
		var arrCurrentCommand = currentCommand.split(",");
		
		// Set the new command
	
		objButton.setAttribute("onclick","weblineFormGroupRemove('" + objDuplicate.id + "',this);");
		
		// Make sure the button is visible
		
		objButton.style.display = "block";
	
		weblineFormDebugConsole("[" + objDuplicate.id + "] weblineFormGroupDuplicateRegister: Delete button onclick updated to weblineFormGroupRemove('" + objDuplicate.id + "',this);",3);
					
	} // end if

} // end function

/**
 * Find the delete button in a group
 *
 * @param object objGroup The object (div/row) of the group
 * @return object|false The button object or false
 */
function weblineFormGroupGetRemoveButton(objGroup) {
	
	weblineFormDebugConsole("[" + objGroup.id + "] weblineFormGroupGetRemoveButton: Search for the delete button and try to update it",3);
					
	var objButton = false;
	
	for(var i=0; i<objGroup.childNodes.length; i++) {
		
		if(objGroup.childNodes[i].onclick) {

			var arrButtonOnclick = objGroup.childNodes[i].getAttribute("onclick").toString().replace(/^[^\{]*\{/ig,"").replace(/}[^\}]*$/ig).split("(");

			if(arrButtonOnclick[0]=="weblineFormGroupRemove") {
			
				weblineFormDebugConsole("[" + objGroup.id + "] weblineFormGroupGetRemoveButton: L1: " + objGroup.childNodes[i].getAttribute("onclick"),4);
					
				objButton = objGroup.childNodes[i];
			
			} // end if
			
		}else{
	
			for(var j=0; j<objGroup.childNodes[i].childNodes.length; j++) {
	
				if(objGroup.childNodes[i].childNodes[j].onclick) {

					var arrButtonOnclick = objGroup.childNodes[i].childNodes[j].getAttribute("onclick").toString().replace(/^[^\{]*\{/ig,"").replace(/}[^\}]*$/ig).replace("javascript:","").split("(");

					arrButtonOnclick[0] = arrButtonOnclick[0].replace("\n","");

					if(arrButtonOnclick[0]=="weblineFormGroupRemove") {
					
						weblineFormDebugConsole("[" + objGroup.id + "] weblineFormGroupGetRemoveButton: L2: " + objGroup.childNodes[i].childNodes[j].getAttribute("onclick").toString().replace("javascript:",""),4);
					
						objButton = objGroup.childNodes[i].childNodes[j];
					
					} // end if
	
				} // end if
	
			} // end for
		
		} // end if
		
	} // end for
	
	return objButton;

} // end function

/**
 * Reset the values of every field within a group
 *
 * @param string ID of the group
 * @param int Disable the fields or not (1 or 0, default=0)
 * @access private
 * @return void
 * @uses weblineFormGroupGetFields()
 * @uses weblineFormGroupResetField()
 */
function weblineFormGroupReset(groupId,disableFields) {

	weblineFormDebugConsole("[" + groupId + "] weblineFormGroupReset: Reset the fields for this group");
	
	// Get an array of fields
	
	var arrFields = weblineFormGroupGetFields(groupId);
	
	// Loop the array of fields and get the objects
	
	for(var i=0; i<arrFields.length; i++) {
	
		// Reset the value
	
		weblineFormGroupResetField(arrFields[i][0],disableFields);
	
	} // end for

} // end function

/**
 * Reset the value of a field within a group
 *
 * @param string ID of the field
 * @param int Disable the field or not (1 or 0, default=0)
 * @access private
 * @return void
 */
function weblineFormGroupResetField(fieldId,disableField) {

	weblineFormDebugConsole("[" + fieldId + "] weblineFormGroupResetField: Reset this field",3);
	
	// Get the object
		
	var objField = document.getElementById(fieldId);
				
	// Reset the value
	
	if(objField.type=="text") objField.value = "";
	if(objField.type=="select-one") objField.selectedIndex = 0;
	if(objField.type=="checkbox") objField.checked = "";
	
	// Hide if requested
	
	if(disableField!=undefined) {
	
		objField.setAttribute("disabled",true);
	
	} // end if

} // end function

/**
 * Process the group and return an array of the fields with all their settings
 *
 * @param string ID of the group
 * @access private
 * @return array Array of fields
 * @uses weblineFormGetFieldSettings()
 */
function weblineFormGroupGetFields(groupId) {

	weblineFormDebugConsole("[" + groupId + "] weblineFormGroupGetFields: Load the fields for this group",3);

	var arrFields = [];
	var iField = 0;
	var arrGroups = arrWeblineForm[weblineFormActivated]['groups'];
	
	for(var i=0; i<arrGroups.length; i++) {
				
		var arrGroup = arrWeblineForm[weblineFormActivated]['groups'][i].split("|");

		if(groupId==arrGroup[1]) {

			arrFields[iField++] = weblineFormGetFieldSettings(arrGroup[0]);

		} // end if
	
	} // end for
	
	return arrFields;

} // end function

/**
 * Initialize the search/autocomplete functionality
 *
 * @param string ID of the form your want the search/autocomplete to be initialized
 * @access private
 * @return void
 */
function weblineFormSearchInit(formId) {
	
	weblineFormDebugGroup("weblineFormSearchInit");
	
	weblineFormDebugConsole("[" + formId + "] weblineFormSearchInit: Initialize search/autocomplete",1);
		
	// Get the fields and start looping them
	
	for(var i=0; i<arrWeblineForm[weblineFormActivated]['search'].length; i++) {
	
		//weblineDebugConsole(arrWeblineForm[weblineFormActivated]['search'][i]);
	
		var arrField = arrWeblineForm[weblineFormActivated]['search'][i].split("|");
		var fieldId = arrField[0];
		var searchUri = arrField[1];
		
		var objField = document.getElementById(fieldId);		
		var searchDiv = document.getElementById(fieldId+"_search");
		
		if(searchDiv) {
		
			searchDiv.style.display = "none";
			
		} // end if
	
		if(BrowserDetect.browser=="Explorer") {
		
			// Register the event handler/listener

			objField.onkeyup = weblineFormSearchCall;
		
		}else{

			// Register the event handler/listener

			var field = document.getElementById(fieldId);
			
			if(field) {
			
				field.addEventListener("keyup",weblineFormSearchCall,false);
			
			}else{
			
				weblineFormDebugConsole("["+formId+"] weblineFormSearchInit: could not add handler on field with id "+fieldId+" .");
			
			} // end if
			
		} // end if
	
	} // end for
	
	WeblineConsole.groupEnd();

} // end function

/**
 * This function is called on each event set by the weblineFormSearchInit function
 *
 * @param event Event object for the field that has an event
 * @access public
 * @return void
 */
function weblineFormSearchCall(event) {
	
	// Cancel previous requests

	cancelPostRequest();

	if(weblineFormSearchActivated!="") {
	
		// Prepare variables

		var objField = event.target;
		var valField = objField.value;
		var fieldId = objField.id;
	
		// Check the length of the value
	
		if(valField.length>2) {
	
			// Clear timer if it has been set

			if(weblineFormSearchTimerID) {

				clearTimeout(weblineFormSearchTimerID);
				weblineFormSearchTimerID  = 0;

			} // end if
		
			// Set new timer

			weblineFormSearchTimerID = setTimeout("weblineFormSearchRequest('" + weblineFormSearchActivated + "')", 500);
	
		} // end if
	
	} // end if

} // end function

/**
 * Show the search div for this field
 *
 * @param string ID of the field
 * @return void
 */
function weblineFormSearchShow(fieldId) {

	// Check if other search is open, hide it if so
	
	if(weblineFormSearchActivated!="") {

		var closeDiv = document.getElementById(weblineFormSearchActivated+"_search");
		closeDiv.style.display = "none";
	
	} // end if
	
	// Get the object of the div

	var searchDiv = document.getElementById(fieldId+"_search");
	
	// Set this field as active
	
	weblineFormSearchActivated = fieldId;
	
	// Re-position the div
	
	weblineFormSearchPosition(searchDiv);
	
	// Resize the search field and the result div
	
	var arrDivWidth = searchDiv.style.width.split("px");
	var inputWidth = arrDivWidth[0];
	
	searchDiv.childNodes[1].childNodes[3].style.width = (inputWidth-19)+"px";
	searchDiv.childNodes[3].style.height = ((inputWidth*2/3)-19)+"px";
	
	// Show the search div
	
	searchDiv.style.display = "";
	
	// Set focus on the input
	
	searchDiv.childNodes[1].childNodes[3].focus();
	
	// Set event handler on the input field
	
	if(BrowserDetect.browser=="Explorer") {

		searchDiv.childNodes[1].childNodes[3].onpropertychange = weblineFormSearchCall;
	
	}else{

		searchDiv.childNodes[1].childNodes[3].addEventListener("keyup",weblineFormSearchCall,false);
		searchDiv.childNodes[1].childNodes[3].addEventListener("change",weblineFormSearchCall,false);
		
	} // end if

} // end function

/**
 * Hide the search div for this field
 *
 * @param string ID of the field
 * @return void
 */
function weblineFormSearchHide(fieldId) {	
	
	// Get the object of the div

	var searchDiv = document.getElementById(fieldId+"_search");
	
	// Clear the active search field
	
	weblineFormSearchActivated = "";
	
	// Hide the search div
	
	searchDiv.style.display = "none";

} // end function

/**
 * Set the value of the search field
 *
 * @param string ID of the field
 * @return void
 */
function weblineFormSearchSet(fieldId,value) {
	
	// Get the object of the div

	var fieldDiv = document.getElementById(fieldId);
	
	// Set value
	
	fieldDiv.value = value;
	
	// Hide search DIV
	
	weblineFormSearchHide(fieldId);
	
	// Validate the form again
	
	weblineFormValidate();

} // end function

/**
 * Execute the request
 *
 * @param string ID of the field
 * @return void
 */
function weblineFormSearchRequest(fieldId) {	
	
	// Get the object of the div

	var searchDiv = document.getElementById(fieldId+"_search");
	var resultDiv = document.getElementById(fieldId+"_searchresult");
	var fieldDiv = document.getElementById(fieldId+"_searchstring").childNodes[3];
	
	// Find the requestUri
	
	var requestUri = false;
	
	for(var i=0; i<arrWeblineForm[weblineFormActivated]['search'].length; i++) {
	
		var arrField = arrWeblineForm[weblineFormActivated]['search'][i].split("|");
		var tempFieldId = arrField[0];
		var tempSearchUri = arrField[1];
		
		if(tempFieldId==fieldId) {
		
			requestUri = tempSearchUri;
		
		} // end if
		
	} // end for
	
	// Set loading icon if no previous result
	
	if(resultDiv.innerHTML=="") {
	
		resultDiv.innerHTML = "<img src=\"/includes/framework/images/notice/loading.gif\" width=\"20\" height=\"20\">";
	
	} // end if
	
	// Launch the request
	
	if(requestUri!=false) {
	
		var params = "fieldid=" + fieldId + "&search=" + encodeURI(fieldDiv.value);

		ajaxPostRequest("weblineFormSearchProcess",requestUri,params,true,true);
		
	} // end if

} // end function

/**
 * Process the search response
 *
 * @param string Response HTML
 * @return void
 */
function weblineFormSearchProcess(response) {

	if(weblineFormSearchActivated!="") {
		
		// Get the active field
	
		var fieldId = weblineFormSearchActivated;
	
		// Get the object of the div where to show the result

		var resultDiv = document.getElementById(fieldId+"_searchresult");	
		
		// Set content

		resultDiv.innerHTML = decodeURI(response);
	
	} // end if

} // end function

/**
 * Position the search result relatively to the field
 *
 * @param searchDiv Object of the searchDiv
 * @access public
 * @return void
 */
function weblineFormSearchPosition(searchDiv) {
	
	// Get form element
	
	var prevEl = searchDiv.parentNode.childNodes[1];

	// Get position of element
	
	var poselx = 0;
	var posely = 0;
	var obj = prevEl;
	
	if (obj.offsetParent) {
		
		do {
			
			poselx += obj.offsetLeft;
			posely += obj.offsetTop;
						
		} while (obj = obj.offsetParent);
		
	} // end if
	
	// Get size of element
	
	var width = prevEl.clientWidth;
	var height = prevEl.clientHeight;
	
	// Move
	
	var movex = poselx;
	var movey = posely;
	
	//weblineFormDebugConsole("x:" + poselx + "px\ny:" + posely + "px\nwidth:" + width + "px\nheight:" + height + "px\nmovex:" + movex + "px\nmovey:" + movey + "px");
	
	// minimum size
	
	if(width<240) width=240;
	if(height<120) height=120;
	
	searchDiv.style.left = movex+"px";
	searchDiv.style.top = movey+"px";
	searchDiv.style.width = (width+1)+"px";
	searchDiv.style.height = Math.round(width*2/3)+"px";
	
} // end function

/**
 * Toggle a DIV to a field (at this point a div=>textarea is working)
 *
 * @param object The object of the link that calls this function (needed for changing icon)
 * @param string ID of the div/field
 * @param string URL we need to POST against using AJAX
 * @return void
 */
function weblineFormToggleDivField(objLink,divID,ajaxUri) {

	// Get the DIV
	
	var objDiv = document.getElementById(divID);
	
	// Get the current content
	
	var contentDiv = objDiv.innerHTML;
	
	// Empty the DIV
	
	objDiv.innerHTML = "";
	objDiv.style.overflowX = "hidden";
	objDiv.style.overflowY = "hidden";

	// Create a textarea
	
	var objField = document.createElement("textarea");
	
	objField.setAttribute("wrap","virtual");
	
	objField.style.width = "198px";
	objField.style.height = "79px";
	objField.style.border = "1px dotted #999999";
	objField.style.backgroundColor = "#eeeeee";
	objField.style.overflowX = "hidden";
	objField.style.overflowY = "scroll";
	objField.style.fontSize = "8pt";
	objField.style.color = "#666666";
	
	// Add the textarea to the div
	
	objDiv.appendChild(objField);
	
	// convert <br> to \n and trim whitespace
	
	contentDiv = trim(br2nl(contentDiv));
	
	// Set its content
	
	objField.value = contentDiv;
	
	// Update icon
	
	objLink.setAttribute("onclick","weblineFormSubmitDivField(this,'" + divID + "','" + ajaxUri + "');");
	objLink.childNodes[0].src = "/includes/framework/images/icon/16x16/disk_blue.gif";

} // end function

/**
 * Submit a field that was converted from a regular DIV using weblineFormToggleDivField
 *
 * @param object The object of the link that calls this function (needed for changing icon)
 * @param string ID of the div/field
 * @param string URL we need to POST against using AJAX
 * @return void
 */
function weblineFormSubmitDivField(objLink,divID,ajaxUri) {

	// Get the DIV
	
	var objDiv = document.getElementById(divID);
	
	// Get the current value of the textarea
	
	var contentField = objDiv.childNodes[0].value;
	
	// Remove the textarea from the DIV
	
	objDiv.removeChild(objDiv.childNodes[0]);
	
	// Set ID on the link
	
	objLink.setAttribute("id",divID+"_button");
	
	// Save the current field as the active one
	
	weblineFormDivFieldActivated = divID + "|" + ajaxUri;
	
	// Update icon
	
	objLink.removeAttribute("onclick");
	objLink.childNodes[0].src = "/includes/framework/images/icon/16x16/disk_blue_disabled.gif";
	
	// Set loading icon
	
	objDiv.innerHTML = "<img src=\"/includes/framework/images/notice/loading.gif\" width=\"20\" height=\"20\">";
	
	// Set params
	
	var params = "content=" + encodeURI(contentField);
	
	// Submit POST request
	
	ajaxPostRequest("weblineFormProcessDivField",ajaxUri,params,true,true);

} // end function

/**
 * Process the AJAX request result
 *
 * @return void
 */
function weblineFormProcessDivField(result) {

	// Get divID and objLink and ajaxUri
	
	var arrIds = weblineFormDivFieldActivated.split("|");
	var divID = arrIds[0];
	var objLink = document.getElementById(arrIds[0]+"_button");
	var ajaxUri = arrIds[1];

	// Get the DIV
	
	var objDiv = document.getElementById(divID);
	
	// Set the content to the DIV and set some styling, also replace newlines with <br>
	
	contentField = trim(nl2br(decodeURI(result)));
	
	objDiv.style.overflowX = "hidden";
	objDiv.style.overflowY = "auto";
	
	objDiv.innerHTML = contentField;
	
	// Update icon
	
	objLink.setAttribute("onclick","weblineFormToggleDivField(this,'" + divID + "','" + ajaxUri + "');");
	objLink.childNodes[0].src = "/includes/framework/images/icon/16x16/edit.gif";

} // end function

//-->

