var browser=navigator.appName;
var W3CDOM = (document.getElementsByTagName && document.createElement); 
var validationRequired;
var validForm;
var displayedValidationAlert;
var password;
var oldpassword;
var email;
var valMsgArray = [];
var acceptChecked = false;

function processAcceptOnClick() {
    //the checkbox always starts out false
    
	if (!acceptChecked) {	   
	   acceptChecked = true;
	}
	else {	  
	   acceptChecked = false;
	}
}

function handleException(e) {

	document.getElementById(regExceptionName).innerHTML="Error occurred: " + e.name; 
	document.getElementById(regExceptionMsg).innerHTML= "Error Message: " + e.message;		
    
    displayMsgBox(msgErrorDivID);
}

//parameters is a semicolon delimited String of metadata about a given field value 
//(value in a dropdown). This metadata is collected for each field value the dropdown.
//If the user selects that field value, this function will be called and that metadata
//will be available.  This gets around the fact that Internet Explorer does not support
//onchange events on option elements (only on their parent select elements).
//Parameters are form field value code, hasConditionalFieldCode flag, 
//comma delimited list of related fields to show if when this value is selected, and a 
//comma delimited list of related fields to hide when this value is selected.
function processFieldValueSelection(selectElement, parameters) {

	try {		
	  
		if (selectElement.hasError) {
	    	removeErrorDropdown(selectElement)
	  	}	  		  	
	  	var fieldValueSelectionParams = parameters.split(";");
	  	if (fieldValueSelectionParams.length > 2) { 
	    	var hasCondFieldCodes = fieldValueSelectionParams[2];
	     	if (hasCondFieldCodes == 'true') {
	    		var fieldValueSelection = fieldValueSelectionParams[1];
	           	if (fieldValueSelectionParams.length > 3 && fieldValueSelectionParams[3] != '') {
	          		var condFieldsToShow = fieldValueSelectionParams[3].split(",");
	              	for (var showI = 0; showI < condFieldsToShow.length; showI++) {
	                	display(condFieldsToShow[showI]);
	              	}
	       		}
	            if (fieldValueSelectionParams.length > 4 && fieldValueSelectionParams[4] != '') {
	            	var condFieldsToHide = fieldValueSelectionParams[4].split(",");
	            	var initFieldFlag = 'true';
	              	for (var hideI = 0; hideI < condFieldsToHide.length; hideI++) {	         	              	    
	                	hide(condFieldsToHide[hideI]);
	              	}
	       		}
	  		 }
     	}    
	}
	catch (e) {
		handleException(e);
	}
	
}

function setDuplicateLoginFlag(dupLoginValue) { 

	try {
		dupLoginCorrectionForm = dupLoginValue;
	}
	catch (e) {
		handleException(e);
	}
	  
}

function setIncorrectPasswordFlag(value) { 

	try {
		incorrectPasswordCorrectionForm = value;
	}
	catch (e) {
		handleException(e);
	}
	  
}

function setValidationFlag(buttonName) { 

	try {
		if (buttonName == 'submitButton') {
		   validationRequired = true;	  
		}
		else {
		   validationRequired = false;	   
		}
	}
	catch (e) {
		handleException(e);
	}
	
	
}

function validateAndSetAction() {	   
	
	try {
	    initValMsgBox();
	    
	    password = '';
	    validForm = true;
	    firstError = null;
	    displayedValidationAlert = false;	 

		if (!validationRequired) {
	        //do nothing. user hit the Cancel button. No client-side validation required.
	    	document.regform.action=cancelUrlFromForm;	
		}
		else {		    
	        var formElements = document.regform.elements;
			for (var i = 0; i < formElements.length; i++) {
		   		//Example of fieldID for fields that need to be validated: validateID_requiredtrue_condFieldfalse
		   		//must be required (isRequired = true), must not be hidden (display != none), 
		   		//and if _condField = false, display must be block or table-row.
		   		var elementValidationID = formElements[i].id.replace(/^\s+|\s+$/g, '') ;
		   		if (elementValidationID == '') {
		      		//do not need to validate. this is not a user input form element
		   		}
		   		else if (elementValidationID.indexOf('_acceptTermstrue') > -1) {	
		   		    validateField(formElements[i], elementValidationID);	   		    		   			  	   		      		  
		   		}                   
		   		else if (elementValidationID.indexOf('_condFieldtrue') > -1) {
		   		    if (elementValidationID.indexOf('_inplay') > -1) {
			 			validateField(formElements[i], elementValidationID);
		       		}
		       		else {
		       		    var indexOfSelectedItem = formElements[i].options.selectedIndex;
		       		    if (indexOfSelectedItem > -1) {
		       		        formElements[i].options[indexOfSelectedItem].value = '';
		       		    }
		       	    }		   	
		   		}
		   		else {		   		    	
		     		//else conditional field = false, so this is a normal field to validate
		     		if (incorrectPasswordCorrectionForm == 'true') {
		     		    if (formElements[i].name && formElements[i].name == 'currentpassword') {
		     		        validatePasswordCorrectionField(formElements[i], elementValidationID);
		     		    }		     		    
		     		}
		     		else {
		     		    validateField(formElements[i], elementValidationID);
		     		}		     		
		   		}
			}
			if (validForm) {			   
			    //disable submit button
		        disableSubmitButton('true');		   
	   			document.regform.action=submitUrlFromForm;
			}
			else {			   
			   if (W3CDOM) {
                    
			   		var valMsg = document.getElementById('validationMsg');
			   		valMsg.innerHTML = validationMessage;
			  
			   		var valDescList = document.getElementById('validationDescList');		   
			   		for (key in valMsgArray) {		  
			      		var valDescItem = document.createElement('li');
			      		valDescItem.id = 'validationDesc' + valMsgArray[key];		      
			      		valDescItem.innerHTML = valMsgArray[key];
			      		valDescList.appendChild(valDescItem);
			   		}
	           		displayMsgBox('message_validation');
				}
				//else an alert was displayed to the user for each type of error.	
			}		    	        	    	        
		}	
	   //took that big if statement from right here
	}
	catch (e) {
		handleException(e);
	}
	
	return validForm;
}


function initValMsgBox() {
   //the validation msg box was hidden as soon as someone left an errored field, but 
   //the validationDescList ul element may still have validationDesc li elements that
   //need to be removed.
   
    var valDescList = document.getElementById('validationDescList');
    var valElements = valDescList.getElementsByTagName('li');
    
    var elemCount = valElements.length;
    var deleteCount = 0;
    if (elemCount > 0) {       
       while (deleteCount < elemCount) {
          deleteCount++;
          valDescList.removeChild(valElements[0]);          
       }
    }
  
    valMsgArray = [];
    //var valMsgArray = new Array();
   
}

function getMaxLength(elementValidationID) {

	try {
		  //example of elementValidationID is validateID_requiredtrue_condFieldtrue_maxlength255
	      //this function will extract the max length using the _maxlength key, which can be last
	      //or not last.
	      var maxLengthKey = '_maxlength';
	      var maxLengthValue = -1;
	
	      var beginningOfMaxLength = elementValidationID.indexOf(maxLengthKey);
	      if (beginningOfMaxLength > -1) {
	         var endOfMaxLength;
	         if (elementValidationID.indexOf('_', beginningOfMaxLength + 1) > -1) {
		   		//then there is one or more keys after the _maxlength key, but we only 
		   		//want the value for the maxlength
		   		endOfMaxLength = elementValidationID.indexOf('_', beginningOfMaxLength + 1);
		 		}
		 	 else {
		         endOfMaxLength = elementValidationID.length;
		     }
		      maxLengthValue = elementValidationID.substring(beginningOfMaxLength + maxLengthKey.length, endOfMaxLength);
	      }
	}
	catch (e) {
		handleException(e);
	}
	
      
	return maxLengthValue;	

}


function validatePasswordCorrectionField(obj, elementValidationID) {

    try {
        var errorstring = '';
        errorstring = valIncorrectPassword;
        writeError(obj, errorstring);
    }
    catch (e) {
		handleException(e);
	} 

}
   
//Normal fields and conditional fields that are in play (not hidden)
function validateField(obj, elementValidationID) {      

	try {
	    var errorstring = '';
	   
        if (obj.value) {
	        var trimmedValue = obj.value.replace(/^\s+|\s+$/g, '') ; 
	        if (elementValidationID.indexOf('validateID_acceptTermstrue') > -1) {	
                    	        	
	        	if (!obj.checked) {	 	        	         	            	   
	        	    errorstring = 'Acceptance of Elsevier\'s terms and conditions is required for registration';
			        writeError(obj, errorstring);	        	   
	        	}		        	       	   			
	        }   
		    else if (trimmedValue == '' || trimmedValue == 'pleaseselect') {		        
		    	if (elementValidationID.indexOf('validateID_requiredtrue') > -1 
		    			&& elementValidationID.indexOf('_isBooleantrue') < 0) {		        	
			        errorstring = valReqFieldAlert;			        		        
		           	writeError(obj, errorstring);
			   	}
			}
			else {
			    //validate that email has an @ sign and that there is text before and after.
			    //this is very lax validation on the client side.           
				if (obj.name == 'email') {				  
			    	if (useEmailAsLogin == 'true' && dupLoginCorrectionForm == 'true') {
		            	errorstring = valDupLogin;
				    	writeError(obj, errorstring);
			       	}	       
		            validateEmail(obj, trimmedValue);
			       	email = trimmedValue;	       
			   	}
			    else if (obj.name == 'confirmemail') {
		        	validateEmailConfirm(obj, trimmedValue);
			    }
			    else if (obj.name == 'currentpassword') {			            
		            oldpassword = trimmedValue;		           
			    }
			    else if (obj.name == 'password') {
					//save this aside so that it can be compared to confirmedpassword
			        password = trimmedValue;			        
		            validateChangedPassword(obj, trimmedValue);		            												
			    }
			    else if (obj.name == 'confirmpassword') {			       
		            validatePassword(obj, trimmedValue);		            			    	
			    }
			    else if (obj.name == 'login' && dupLoginCorrectionForm == 'true') {
		            errorstring = valDupLogin;
					writeError(obj, errorstring);
			   	}
		  
			    //check data value lengths for fields excluding dropdown boxes and checkboxes.
			    //For dropdown boxes, if for some crazy reason a value has been provided to the 
			    //user in a dropdown and that value exceeds the max length, that is nothing 
			    //that the user can fix.  Max lengths for dropdowns will be validated on the 
			    //server side though.  Values for checkboxes will also be validated on the server.
			 
			    if (obj.nodeName == 'INPUT') {
			    	if (elementValidationID.indexOf('_isBooleantrue') > -1 || obj.type == 'checkbox') {
			        	//do nothing - don't need to validate max length
			      	}	     
			      	else {
		            	var maxLength = getMaxLength(elementValidationID);
				 
				 		if (obj.value.length > maxLength) {						 		    
						    errorstring = obj.name + ' ' + valMaxLenAlert + ' ' + maxLength;  						 	
						 	writeError(obj, errorstring);
				 		}
			      }	      
			   }	
			}	            
	    }
	    else {
	        //this object did not have a value
	        if (elementValidationID.indexOf('validateID_requiredtrue') > -1 
		    			&& elementValidationID.indexOf('_isBooleantrue') < 0) {		        	
			        errorstring = valReqFieldAlert;			        		      	
		           	writeError(obj, errorstring);
			}			
	    }
	    		    	    	    
	}
	catch (e) {
		handleException(e);
	}
}

//find out the index of the @ sign
//if there is one, make sure its not 0 or the last position
//make sure there's only 1 @ sign
function validateEmail(obj, trimmedValue) {
	try {
	    var validEmail = true;
		var indexOfAtSign = trimmedValue.indexOf('@');
		if (indexOfAtSign > -1) {
		   var lastIndexOfEmail = trimmedValue.length - 1;
		   //ensure that the @ sign is not the first character nor the last.
		   if (indexOfAtSign == 0 || indexOfAtSign == lastIndexOfEmail) {
			validEmail = false;
		   }
		   else if (trimmedValue.indexOf('@', indexOfAtSign + 1) > -1) {
		       validEmail = false;
		   } 
		   else {
		       var indexOfDot = trimmedValue.indexOf('.', indexOfAtSign);
			   if (indexOfDot > -1) {
			      if (indexOfDot == 0 || indexOfDot == lastIndexOfEmail) {
			         validEmail = false;
			      }
			   }
			   else {
			       validEmail = false;
			   } 
		   }		    
		}
		else {
		    validEmail = false;
		}
	
		if (!validEmail) {		         
		   errorstring = valInvalidEmailAlert;   		   
		   writeError(obj, errorstring);
		}
	}
	catch (e) {
		handleException(e);
	}
	
}	


function validateEmailConfirm(obj, trimmedConfirmedEmail) {

	try {
	      var emailMatches = true;

	      if (!email) {
	         emailMatches = false;
	      }
	      else if (email != trimmedConfirmedEmail) {
	         emailMatches = false;
	      }
	
	      if (!emailMatches) {	              
		      errorstring = valInvalidConfirmEmailAlert;		  
		      writeError(obj, errorstring);   
	      }
	}
	catch (e) {
	    handleException(e);
	}
      
}

function validatePassword(obj, trimmedConfirmPassword) {

	try {
	    var validPassword = true;
	   	if (!password) {
	    	//then the user did not provide a value for the first password field
	  		validPassword = false;
	   	}
	   	else if (password != trimmedConfirmPassword) {
	    	validPassword = false;
	   	}
	
	
	   	if (!validPassword) {	    		      			   		      
	      	errorstring = valInvalidConfirmPasswordAlert;	   		
	   		writeError(obj, errorstring);          
	   	}
	}
	catch (e) {
	    handleException(e);
	}
	
}


function validateChangedPassword(obj, trimmedNewPassword) {
	
	try {
		var changedPassword = false;
	
		//New password is being passed into here. And user should have already provided a value for old
		//password in the field before this one.
	
		if (trimmedNewPassword != oldpassword) {
	    	changedPassword = true;
		}
	
		//else if no value has been provided for password, then some other validation will throw an error.
	
		if (!changedPassword) {	    		      	    
	      	errorstring = valInvalidChgPasswordAlert;	   		
	   		writeError(obj, errorstring); 
		}
	}
	catch (e) {
	    handleException(e);
	}

}

function writeError(obj,message) {

    try {
    	validForm = false;       

		if (W3CDOM) {
			if (!obj.hasError) {
			    obj.className += ' error';
				//If this is a dropdown field (nodeName = SELECT), then do not 
				//want to override its onchange event. removeError(obj) function
				//will handle it.
				if (obj.nodeName == 'INPUT') {
				    if (obj.id.indexOf('_acceptTermstrue') > -1) {				        
				        obj.onclick = removeErrorCheckbox;	
				    }				    				   
				    else {
				        obj.onchange = removeErrorTextField;
				    }			    			   		
				}
				obj.hasError = true;
			}
			var msgExists = false;
			for (var i = 0; i < valMsgArray.length; i++) {
			   if (valMsgArray[i] == message) {
			      msgExists = true;
			      break;
			   }
			}	
			if (!msgExists) {
			    valMsgArray[valMsgArray.length] = message;
			}	  			    	      
		}
		else {
		    if (!displayedValidationAlert) {
	        	alert(message);
		      	displayedValidationAlert = true;
		    }	           
		    obj.hasError = true;
		}
		if (!firstError) {
			firstError = obj;
	    }
    }
    catch (e) {
        handleException(e);
    }  
  
}


//this is the removeError function for dropdown boxes. The removeError function could not
//be called on dropdown box change events because dropdown boxes have other change event logic.
function removeErrorDropdown(selectElement) {
    
    
    try {
    	if (W3CDOM) {
      		selectElement.className = selectElement.className.substring(0,selectElement.className.lastIndexOf(' '));
	  		//selectElement.parentNode.removeChild(selectElement.hasError);
	  		hideMsgBox('message_validation');	
	  		selectElement.hasError = null;
	  		this.onchange = null;	  		  		
		}
    }
    catch (e) {
        handleException(e);
    }
    
}
    
//this is the removeError function for input boxes.
function removeErrorTextField() {        
    
	try {
		if (W3CDOM) {
	    	this.className = this.className.substring(0,this.className.lastIndexOf(' '));
		  	//this.parentNode.removeChild(this.hasError);
		  	this.hasError = null;
		  	this.onchange = null;
		  	hideMsgBox('message_validation');	
	    }
	    setDuplicateLoginFlag('false');  
	    setIncorrectPasswordFlag('false');	
		}
	catch (e) {
        handleException(e);
    }
	
}

function removeErrorCheckbox() {
       
    processAcceptOnClick();
    
    try {
		if (W3CDOM) {
	    	this.className = this.className.substring(0,this.className.lastIndexOf(' '));		  	
		  	this.hasError = null;
		  	this.onclick = processAcceptOnClick;
		  	hideMsgBox('message_validation');	
	    }	    
	}
	catch (e) {
        handleException(e);
    }
    
	
	
}
    
//called for every field where isConditionalField = true (_condFieldtrue)
//also called if the field is displayed due to some user input, but then later user changes their input.
function hide(id) {

	try {
		ge = document.getElementById(id);
		ge.style.display = 'none';		
		flagConditionalFieldForValidation(ge, 'false');
	}
	catch (e) {
        handleException(e);
    }
	
}

function hideMsgBox(msgBoxDivID) {

  var msgBox = document.getElementById(msgBoxDivID);
  msgBox.style.display = 'none';
  
}
      
function displayMsgBox(msgBoxDivID) {

    var msgBox = document.getElementById(msgBoxDivID);
    msgBox.style.display = 'block';

}


function disableSubmitButton(doDisable) {

	//var submitButton = document.getElementById('submitButton');
	//submitButton.disabled=doDisable;
	var submitButtons = document.getElementsByName('submitButton');
	for (var i = 0; i < submitButtons.length; i++) {
	   submitButtons[i].disabled=doDisable;
	}

}
//As users select values in dropdown boxes, conditional fields may need to be displayed.
//Once these conditional fields are displayed, if they are required, they need to be
//flagged so that the validation routine will know to validate them.
function display(id) {
	//get the table row element & make it visible
	//id of the row is the same name as the select or input field within it
    try {
        var listItems = document.regform.getElementsByTagName('li');
        for (var i = 0; i < listItems.length; i++) {
            if (listItems[i].id == id) {               
               listItems[i].style.display = 'list-item';
               //listItems[i].style.display = 'block';
               flagConditionalFieldForValidation(listItems[i], 'true');
               break;
            }            
        }
        
       
    	//var condFieldRow = document.getElementById(id);
    	//Both IE and Mozilla Firefox likes list-item
    	//condFieldRow.style.display = 'list-item';
	    //if (browser.indexOf("Microsoft Internet Explorer") > -1) {
		//flagConditionalFieldForValidation(condFieldRow, 'true');
    }
	catch (e) {
        handleException(e);
    }
   

}
      
   //An example li ID subdivisions_CA.  That li should have a select element in it
   //that has the same name, but it will have an id that looks something like
   //validateID_requiredtrue_condFieldtrue_inplay.  Need to find the select element using
   //the subdivisions_CA name and then append _inplay to it's id.
   //In Firefox, you can find the select element by name using getElementByName(),
   //But in IE, getElementByName("subdivisions_CA") will return any elements with that
   //value as the name or the ID! (which would include the table row that we don't want).

function flagConditionalFieldForValidation(rowElement, needValidation) {
      
    try {
        //for any select or input elements in this row, flag them as _inplay so that the 
		//validation routine will know that they need to be validated.
		var selectElements = rowElement.getElementsByTagName('select');
	    for (var selectI = 0; selectI < selectElements.length; selectI++) {
			if (needValidation == 'true') {
			    //if (selectElements[selectI].id.indexOf('_inplay') < 0) {
			        selectElements[selectI].id += '_inplay';
			    //}
		    }
		    else {
		    	if (selectElements[selectI].id.indexOf('_inplay') > -1) {
		        	var indexOfInplay = selectElements[selectI].id.indexOf('_inplay');
			   		var newId = selectElements[selectI].id.substring(0, indexOfInplay);
		           	selectElements[selectI].id = newId;		        
		        }
		    }  
	     }

		 var inputElements = rowElement.getElementsByTagName('input');
	     for (var inputI = 0; inputI < inputElements.length; inputI++) {
		 	if (needValidation == 'true') {
		    	inputElements[inputI].id += '_inplay';}
	        else {
	        	if (selectElements[selectI].id.indexOf('_inplay') > -1) {
	            	var indexOfInplay = selectElements[selectI].id.indexOf('_inplay');
	                var newId = selectElements[selectI].id.substring(0, indexOfInplay);
	                selectElements[selectI].id = newId;
				}
		    }             
	     }
    }
    catch (e) {
        handleException(e);
    }    
	
}
      



