/****h* top/FormUtil
* *****************************************************************************
* SYNOPSIS
* Helpers for HTML Forms
* HREF_FILE_NAME
*
* DESCRIPTION
* This file contains helper functions or classes related to HTML Form 
* and associated input
*
* UNIT TESTS
* Input Validation: href:UNIT_TEST_PATH/FieldValidation/index.htm
******************************************************************************/

/****f* FormUtil/submitEvent
* *****************************************************************************
* FUNCTION
* submitEvent: completes the action of a form and submit the form.
*
* DESCRIPTION
* This function retrieves the form which name is passed as a parameter, and its action.
* It completes this action with the event, portletid and/or pageid passed as parameters
* and submits the form.
*
* USAGE
* submitEvent(ev, formName, portletid, pageid)
* submitEvent('air_then_fare.otherfares','avail_then_fare.jsp')
*
* PARAMETERS
* ev - name of the wfevent that is added in the action
* formName - Name of the form
* portletid - if this parameter is given, the function replace the portletid of the action with it.
* pageid - if this parameter is given, the function replace the pageid of the action with it.
* RETURN VALUE
* void
******************************************************************************/
function submitEvent(ev, formName, portletid, pageid)
{
	var nForm=document.forms[formName];
	nForm.action = nForm.action.replace(/wfevent=[\w.]+/, "wfevent="+ev);
	if (portletid) {
    	nForm.action = nForm.action.replace(/portletid=[\w.]+/, "portletid="+portletid);    
	}
	if (pageid) {
    	nForm.action = nForm.action.replace(/pageid=[\w.]+/, "pageid="+pageid);    
	}
	nForm.submit();
}

/****f* FormUtil/findFieldByName
* *****************************************************************************
* FUNCTION
* findFieldByName: Find the place of an input field in an HTML Form with its name.
*
* DESCRIPTION
* This function enables to find the place of an input field in an HTML Form with its name.
* The number returned can then be reused with document.myForm.elements[theNumber] for example
* to work on it
* This function is used when a direct call like document.myForm.nameElements is not possible because
* the name of the field contains special characters.
*
* USAGE
* findFieldByName(name,myForm)
* findFieldByName("nameField",document.airSearchFormName)
*
* PARAMETERS
* name - Name of the parameter to search in the Form
* myForm - Name of the Form whose the parameter to search is part of
*
* RETURN VALUE
* the index of the field in the document.myForm.elements[] array
******************************************************************************/
function findFieldByName(name,myForm){
	var formLength = myForm.elements.length;
	for(n = 0 ; n < formLength ; n ++){
		if(myForm.elements[n].name == name) {
			return n;
		}
	}
	return -1;
}


/****f* FormUtil/findFieldByNameAndTagName
* *****************************************************************************
* FUNCTION
* findFieldByNameAndTagName: optimized function that finds the place of an input field in an HTML Form with its name.
*
* DESCRIPTION
* Optimized function which runs all the 'tagName' tags of a form, and returns
* the element which has the requested name.
* If this element does not exist, it returns null.
* For performance reasons, this function should be used instead of findFieldByName,
* when the tag of the element is known.
*
* USAGE
* findFieldByNameAndTagName(name, tagName, myForm)
* findFieldByNameAndTagName("nameField","input",document.airSearchFormName)
*
* PARAMETERS
* name - Name of the parameter to search in the Form
* tagName - tagName of the parameter to search in the Form
* myForm - form name
*
* RETURN VALUE
* a pointer on the element found. If no element found, it return null.
******************************************************************************/
function findFieldByNameAndTagName(name, tagName, myForm) {
  	
  	var nodes = getPortlet(myForm).getElementsByTagName(tagName);
  	var n = nodes.length;
	for(var i=0; i<n; i++)
	{
		if(nodes[i].name == name)
		{
			return nodes[i];
		}
	}
	return null;
}

/****h* top/FieldValidation
* *****************************************************************************
* SYNOPSIS
* Helpers for validating input fields. See also PortletUtil.
*
* DESCRIPTION
* Validation functions used by the etv:validate validation mechanism      
* See portlet_util.js/validate for the code which calls these functions 
*
* UNIT TESTS
* href:UNIT_TEST_PATH/FieldValidation/index.htm
******************************************************************************/


/****f* FieldValidation/etvValidateNotBlank
* *****************************************************************************
* FUNCTION
* etvValidateNotBlank: Test that a field value is not blank.
*
* PREREQUISITE
* the global variable mandatoryField should be defined and contain the error message 
* to be displayed if the field is not blank.
*
* DESCRIPTION
* Check if the field if blank (\s character). This 'NotBlank' should be set on HTML tag
* using the etv:validate attribute and the validate method from the portlet object will then
* call the validator function (see PortletUtil.js) for more details.
*
* USAGE
* etvValidateNotBlank(field)
*
* PARAMETERS
* field: name of the field tested.
*
* RETURN VALUE
* The error message defined in the mandatoryField string (prerequisite), null otherwise
******************************************************************************/
function etvValidateNotBlank(field)
{
	// Trim whitespace.
	var value = field.value.replace(/^\s+|\s+$/g,'');
	
	if (!value.length)
		return mandatoryField; 

	return null;	
}

/****f* FieldValidation/etvValidateNotBlankIfOtherField
* *****************************************************************************
* FUNCTION
* etvValidateNotBlankIfOtherField : Test that a field value is not blank if another field is filled as well
* PARAMETERS
* field - name of the field tested.
* otherFieldName - name of the other field 
* RETURN VALUE
* The error message defined in the mandatoryField string (prerequisite)
******************************************************************************/
function etvValidateNotBlankIfOtherField(field,otherFieldName)
{
	var portlet=getPortlet(field);
	var otherField=portlet.getElementsByName(otherFieldName,1)[0];

	// Trim whitespace.
	var value = field.value.replace(/^\s+|\s+$/g,'');
	var otherValue = otherField.value.replace(/^\s+|\s+$/g,'');
	
	if (otherValue.length>0) {
    	if (!value.length)
    		return mandatoryField;
    }

	return null;	
}

/****f* FieldValidation/etvValidateNotBlankIfOtherChecked
* *****************************************************************************
* FUNCTION
* etvValidateNotBlankIfOtherChecked : Test that a field value is not blank if another field is checked
* PARAMETERS
* field - name of the field tested.
* otherFieldName - name of the other field 
* RETURN VALUE
* The error message defined in the mandatoryField string (prerequisite)
******************************************************************************/
function etvValidateNotBlankIfOtherChecked(field,otherFieldName)
{
	var portlet=getPortlet(field);
	var otherField=portlet.getElementsByName(otherFieldName,1)[0];

	// Trim whitespace.
	var value = field.value.replace(/^\s+|\s+$/g,'');
	var otherValueChecked = otherField.checked;
	
	if (otherValueChecked==true) {
    	if (!value.length)
    		return mandatoryField;
    }

	return null;	
}

/****f* FieldValidation/etvValidatePattern
* *****************************************************************************
* FUNCTION
* etvValidatePattern : Test whether a field value matches the given regular expression pattern 
* PARAMETERS
* field - name of the field tested.
* param - regular expression 
* RETURN VALUE
* The error message defined in the invalidFormat string (prerequisite)
******************************************************************************/
function etvValidatePattern(field, param)
{
	// Trim whitespace.
	var value = field.value.replace(/^\s+|\s+$/g,'');
	
	var regex = new RegExp(param);
	if (!regex.test(value))
		return invalidFormat; 

	return null;	
}

/****f* FieldValidation/etvValidateEmail
* *****************************************************************************
* FUNCTION
* etvValidateEmail : Test whether a field value matches an email address pattern 
*
* DESCRIPTION
* Test whether a field value matches an email address pattern 
* options can be 1 = blank is allowed
*                2 = multiple comma separated is allowed
*                3 = both of the above.
*
* PARAMETERS
* field - name of the field tested.
* options - options can be 1 = blank is allowed
*                          2 = multiple comma separated is allowed
* 			   3 = both of the above.
* RETURN VALUE
* The error message defined in either addressAllowed or the invalidEmail string (prerequisite)
******************************************************************************/
function etvValidateEmail(field, options)
{
	// Trim whitespace.
	var value = field.value.replace(/^\s+|\s+$/g,'').toLowerCase();
	
	// if blank is allowed and no value -- no error;
	if (!value && options && (options & 1))
		return null;
	
	// if blank raise mandatoryField error message instead of InvalidEmail
	if(value.length == 0)
		return mandatoryField; 
	
	// split on a comma followed by zero or more spaces in case we have multiple addresses.
	// In fact comma is a valid email address character - oh well...
	var aV = value.split(/, */);
	
	// If bit 2 of options is not set we don't allow multiples.
	if (aV.length > 1 && !(options & 2))
		return addressAllowed;
	
	// simple email address regexp...
	// does not accept IP domain names or some valid punctuation charaters (e.g. comma) in the name part.
	// search the web for more complex rexeps if necessary.
	var regex = /^[_\.\'0-9a-z-]+@([0-9a-z][0-9a-z-]*\.)+([a-z]{2,4})+$/;
		
	for (var i=0; i<aV.length; i++)
		if (!regex.test(aV[i]))
			return invalidEmail; 
		
	return null;
}

/****h* top/MandatoryFields
* *****************************************************************************
* SYNOPSIS
* Helpers for validating the profile fields dependencies
*
* DESCRIPTION
* Functions used to display and remove warning messages about missing mandatory fields near each profile group      
* 
* UNIT TESTS
* Input Validation: href:UNIT_TEST_PATH/ProfileFields/index.htm
******************************************************************************/

function MandatoryFields(portlet,totalGroup)
{
	this.ListFields = new Array();
	this.ListFieldsMandatory = new Array();
	this.ListFieldsToBeMandatory = new Array();
	this.ListBlankFields = new Array();
	this.p = portlet;
	this.totalGroup = totalGroup;
	
	/****f* MandatoryFields/addMandatoryFields
	* *****************************************************************************
	* FUNCTION
	* addMandatoryFields: add a field to the list of mandatory fields.
	* PARAMETERS
	* formName - name of the form containing the field.
	* inputTag - name of the field.
	* alreadyMand - field already marked as mandatory
	* toBeMand - field forced to be mandatory
	*
	* USAGE
	* addMandatoryFields(formName,inputTag,alreadyMand,toBeMand).
	*
	* RETURN VALUE
	* void
	******************************************************************************/
	MandatoryFields.prototype.addMandatoryFields = function (formName,inputTag,alreadyMand,toBeMand)
	{
		var myForm = document.forms[formName];
		
		// We look for each type of input field, amongst "input" "select" and "textArea" tags
		var inputField = findFieldByNameAndTagName(inputTag,"input",myForm);
		if (!inputField)
			inputField = findFieldByNameAndTagName(inputTag,"select",myForm);
		if (!inputField)
			inputField = findFieldByNameAndTagName(inputTag,"textArea",myForm);
		
		var alreadyMandatory = alreadyMand;
		var toBeMandatory = toBeMand;
		
		if (inputField)
		{	
			this.ListFields.push(inputField);
			this.ListFieldsMandatory.push(alreadyMandatory);
			this.ListFieldsToBeMandatory.push(toBeMandatory);
		}
	}
	
	/****f* MandatoryFields/checkMandatoryFields
	* *****************************************************************************
	* FUNCTION
	* checkMandatoryFields: used to display/remove the mandatory icons
	* PARAMETERS
	* formName - form in which we are testing.
	* inputTag - name of the field.
	* missingFields - message displayed
	*
	* USAGE
	* checkMandatoryFields(formName,inputTag,missingFields).
	*
	* RETURN VALUE
	* void
	******************************************************************************/
	MandatoryFields.prototype.checkMandatoryFields = function (formName,inputTag,missingFields)
	{
		var myForm = document.forms[formName];
		
		// We look for each type of input field, amongst "input" "select" and "textArea" tags
		var inputField = findFieldByNameAndTagName(inputTag,"input",myForm);
		if (!inputField)
			inputField = findFieldByNameAndTagName(inputTag,"select",myForm);
		if (!inputField)
			inputField = findFieldByNameAndTagName(inputTag,"textArea",myForm);
				
		if (inputField)
		{	
			var inputFieldValue = inputField.value;
			
			this.removeMessage(missingFields);
			
			if (inputFieldValue.length != null && inputFieldValue.length != 0) {
				var removeMsg = true;
				for(i=0;i<this.ListFields.length;i++){
					if(this.ListFieldsMandatory[i] == "false" && this.ListFieldsToBeMandatory[i] == "true"){
						this.p.DisplayMandatoryIcon(this.ListFields[i],"profMandIcon");
						if(this.ListFields[i].nodeName == "SELECT"){
							if(this.ListFields[i].value == "00"){
								removeMsg = false;
								this.ListBlankFields.push(this.ListFields[i]);
							}
						}
						else{
							if(this.ListFields[i].value == "" ){
								removeMsg = false;
								this.ListBlankFields.push(this.ListFields[i]);
							}
						}
					}
				}
				if(this.ListBlankFields.length > 0)
					this.displayMessage(missingFields);
				
				this.totalGroup.displayAllGroups();
				
				
				if(removeMsg){
					this.removeMessage(missingFields);
				}
			}
			else{
				var removeMandIcon = true;
				var mandField = false;
				for(i=0;i<this.ListFields.length;i++){
					if(this.ListFields[i].nodeName == "SELECT")
					{
						removeMandIcon = true;
					}
					else{
					 	if(this.ListFields[i].value != "" && this.ListFieldsToBeMandatory[i] == "true"){
							removeMandIcon = false;
						}
					}
					
				}
				
				if(removeMandIcon){
					for(i=0;i<this.ListFields.length;i++){
						if(this.ListFieldsMandatory[i] == "false" && this.ListFieldsToBeMandatory[i] == "true"){
							this.p.DisplayMandatoryIcon(this.ListFields[i],"");
						}
					}
					this.totalGroup.displayAllGroups();
					this.removeMessage(missingFields);
				}
				else{
					for(i=0;i<this.ListFields.length;i++){
						if(this.ListFieldsMandatory[i] == "false" && this.ListFieldsToBeMandatory[i] == "true"){
							this.p.DisplayMandatoryIcon(this.ListFields[i],"profMandIcon");
							mandField = true;
						}
					}
					if(mandField){
						this.displayMessage(missingFields);
						this.totalGroup.displayAllGroups();
					}
				}
			}	
		}	
	}
	
	/****f* MandatoryFields/displayMessage
	* *****************************************************************************
	* FUNCTION
	* displayMessage: used to display the warning message
	* PARAMETERS
	* missingFields - warning message.
	*
	* USAGE
	* displayMessage(missingFields).
	*
	* RETURN VALUE
	* void
	******************************************************************************/
	MandatoryFields.prototype.displayMessage = function (missingFields)
	{
	       show(missingFields);
	}
	
	
	/****f* MandatoryFields/removeMessage
	* *****************************************************************************
	* FUNCTION
	* removeMessage: used to remove the warning message
	* PARAMETERS
	* missingFields - warning message.
	*
	* USAGE
	* removeMessage(missingFields).
	*
	* RETURN VALUE
	* void
	******************************************************************************/
	MandatoryFields.prototype.removeMessage = function (missingFields)
	{
		hide(missingFields);
	}
}

/****f* FormUtil/validateMyForm
* *****************************************************************************
* FUNCTION
* validateMyForm: used to validate a form.
* FUNCTION
* This function checks all the content of a form, and might display warning message
* if the form is not correctly filled in.
* PARAMETERS
* myForm - name of the form.
*
* USAGE
* validateMyForm(myForm).
*
* RETURN VALUE
* boolean
******************************************************************************/
function validateMyForm(myForm){
	var nForm = document.forms[myForm];
	var portlet=getPortlet(nForm);	
	portlet.clearMessages();
	portlet.validate(nForm);
	portlet.displayMessages();
	if (portlet.countMessages())
		return false;
	else
		return true;	
}



