// On page load, this array is populated with all the things which need to
// hide/show when the co-borrower radio is toggled.
var coBorrowerElements = new Array(0);

// On form validation, this array is populated with validation error messages
var validationMessages = new Array(0);

// A library of regular expressions which aid in form validation in the
// validateValidFields() function
var regexpLib = {
  email: /^.+\@(\[?)[a-zA-Z0-9\-\.]+\.([a-zA-Z]{2,3}|[0-9]{1,3})(\]?)$/,
  integer: /^\d+$/,
  currency: /^[1-9]\d{2,4}([\.]\d\d)?$/, // float is a reserved word in Safari
  date: /^[0-9]{1,2}\/[0-9]{1,2}\/[0-9]{2,4}$/
};

var contactfields;
var cocontactfields;


// An object containing all the rules and response messages of form validation
var validation = {
  
  // All required fields
  required: {
    // If necessary, you can link to the field which has caused the error
    LoanApplication_amountrequired: 'Please enter the amount required.',
    LoanApplication_reason: 'Please describe the reason for your loan.',
    LoanApplication_previousloan: 'Please indicate whether or not you have had a loan before.',
    LoanApplication_coborrower: 'Please indicate whether or not you would like to include a co-borrower.',
    LoanApplication_howdidhear: 'Please tell us how you heard about us.',
    LoanApplication_title: 'Please select the title of the main borrower.',
    LoanApplication_firstname: 'Please enter the first name of the main borrower.',
    LoanApplication_lastname: 'Please enter the surname of the main borrower.',
    LoanApplication_maritalstatus: 'Please select the marital status of the main borrower.',
    LoanApplication_dob: 'Please enter the date of birth of the main borrower.',
    LoanApplication_nbrdependants: 'Please select the number of dependants the main borrower supports.',
    LoanApplication_resident: 'Please indicate whether or not you are a NZ resident.',
    LoanApplication_bestcontact: 'Please select the best contact number for the main borrower.',
    LoanApplication_email: 'Please enter an email address for the main borrower.',
    LoanApplication_addressstreet: 'Please enter the street address of the main borrower.',
    LoanApplication_addresscity: 'Please enter the city of the main borrower.',
    LoanApplication_addresshowlong: 'Please select how long the main borrower has lived at this address.',
    LoanApplication_propertystatus: 'Please select the type of residency the main borrower\'s address is.',
    LoanApplication_propertyexpense: 'Please enter how much the main borrower pays for their residence.',
    LoanApplication_propertyexpenseperiod: 'Please indicate how often the main borrower pays for their residence.',
    LoanApplication_occupation: 'Please enter the occupation of the main borrower.',
    LoanApplication_employer: 'Please enter the main borrower\'s employer.',
    LoanApplication_occupationhowlong: 'Please select how long the main borrower has worked at their current place of employment.',
    LoanApplication_occupationtype: 'Please select the employment type of the main borrower.',
    LoanApplication_paytaxed: 'Please enter the main borrower\'s take home pay.',
    LoanApplication_payperiod: 'Please select the main borrower\'s pay period.',
    LoanApplication_acceptprivacy: 'The main borrower must accept the privacy conditions to continue.',
    LoanApplication_acceptterms: 'The main borrower must accept the terms and conditions to continue.'
  },
  
  // All fields which expect a particular format based on the regular
  // expression library
  valid: {
    LoanApplication_dob: {format: regexpLib.date, message: 'Please enter a valid date of birth for the main borrower.'},
    LoanApplication_email: {format: regexpLib.email, message: 'Please enter a valid email address.'}
   },
  
  // All fields whose validation depends on the value of another field
  requiredLink: {
    // I.e. LoanApplication_cotitle is required if LoanApplication_coborrower='yes'
    LoanApplication_cotitle: {depends: 'LoanApplication_coborrower', value: 'yes', message: 'Please select the title of the co-borrower.'},
    LoanApplication_cofirstname: {depends: 'LoanApplication_coborrower', value: 'yes', message: 'Please the first name of the co-borrower.'},
    LoanApplication_colastname: {depends: 'LoanApplication_coborrower', value: 'yes', message: 'Please the surname of the co-borrower.'},
    LoanApplication_comaritalstatus: {depends: 'LoanApplication_coborrower', value: 'yes', message: 'Please select the marital status of the co-borrower.'},
    LoanApplication_codob: {depends: 'LoanApplication_coborrower', value: 'yes', message: 'Please enter the date of birth of the co-borrower.'},
    LoanApplication_conbrdependants: {depends: 'LoanApplication_coborrower', value: 'yes', message: 'Please select the number of dependants the co-borrower supports.'},
    LoanApplication_coresident: {depends: 'LoanApplication_coborrower', value: 'yes', message: 'Please indicate whether or not you are a NZ resident.'},
    LoanApplication_cobestcontact: {depends: 'LoanApplication_coborrower', value: 'yes', message: 'Please select the best contact number for the co-borrower.'},
    LoanApplication_coemail: {depends: 'LoanApplication_coborrower', value: 'yes', message: 'Please enter an email address for the co-borrower.'},
    LoanApplication_cooccupation: {depends: 'LoanApplication_coborrower', value: 'yes', message: 'Please enter the occupation of the co-borrower.'},
    LoanApplication_coemployer: {depends: 'LoanApplication_coborrower', value: 'yes', message: 'Please enter the co-borrower\'s employer.'},
    LoanApplication_cooccupationhowlong: {depends: 'LoanApplication_coborrower', value: 'yes', message: 'Please select how long the co-borrower has worked at their current place of employment.'},
    LoanApplication_cooccupationtype: {depends: 'LoanApplication_coborrower', value: 'yes', message: 'Please select the employment type of the co-borrower.'},
    LoanApplication_copaytaxed: {depends: 'LoanApplication_coborrower', value: 'yes', message: 'Please enter the co-borrower\'s take home pay.'},
    LoanApplication_copayperiod: {depends: 'LoanApplication_coborrower', value: 'yes', message: 'Please select the co-borrower\'s pay period.'},
    LoanApplication_coaddressstreet: {depends: [{field: 'LoanApplication_coborrower', value: 'yes'}, {field: 'LoanApplication_sameasmain', value: false}], message: 'Please enter the street address of the co-borrower.'},
    LoanApplication_coaddresscity: {depends: [{field: 'LoanApplication_coborrower', value: 'yes'}, {field: 'LoanApplication_sameasmain', value: false}], message: 'Please enter the city of the co-borrower.'},
    LoanApplication_coaddresshowlong: {depends: [{field: 'LoanApplication_coborrower', value: 'yes'}, {field: 'LoanApplication_sameasmain', value: false}], message: 'Please select how long the co-borrower has lived at this address.'},
    LoanApplication_copropertystatus: {depends: [{field: 'LoanApplication_coborrower', value: 'yes'}, {field: 'LoanApplication_sameasmain', value: false}], message: 'Please select the type of residency the co-borrower\'s address is.'},
    LoanApplication_copropertyexpense: {depends: [{field: 'LoanApplication_coborrower', value: 'yes'}, {field: 'LoanApplication_sameasmain', value: false}], message: 'Please enter how much the co-borrower pays for their residence.'},
    LoanApplication_copropertyexpenseperiod: {depends: [{field: 'LoanApplication_coborrower', value: 'yes'}, {field: 'LoanApplication_sameasmain', value: false}], message: 'Please indicate how often the co-borrower pays for their residence.'},
    LoanApplication_coacceptprivacy: {depends: 'LoanApplication_coborrower', value: 'yes', message: 'The co-borrower must accept the privacy conditions to continue.'},
    LoanApplication_coacceptterms: {depends: 'LoanApplication_coborrower', value: 'yes', message: 'The co-borrower must accept the terms and conditions to continue.'}
  }
  
}

// Perform global initialisation
window.onload = function() {

  findCoBorrowerElements();
  initialiseEvents();
  toggleCoBorrower();
  toggleCoAddressDisabledState();

}

// Create an index of all fields which hide/show depending on if user wants a co-borrower or not
// Takes no arguments
function findCoBorrowerElements() {
  coBorrowerElements = getElementsByClassName('column3');
}

function getElementsByClassName(clsName) {

  var clsEls = new Array(0);
  var elements = document.getElementsByTagName("*");
  
  for (var i=0; i<elements.length; i++) {
    if (elements[i].className.indexOf(" ") >= 0) {
      var classes = elements[i].className.split(" ");
      for(var j=0; j<classes.length; j++) {
        if(classes[j] == clsName)
          clsEls.push(elements[i]);
      }
    } else if (elements[i].className == clsName)
      clsEls.push(elements[i]);
  }
  
  return clsEls;
  
}

// Attach user event hooks to fields
// Takes no arguments
function initialiseEvents() {

  document.getElementById('LoanApplication_coborrower_yes').onclick = document.getElementById('LoanApplication_coborrower_no').onclick = toggleCoBorrower;
  
  document.getElementById('LoanApplication_sameasmain').onclick = toggleCoAddressDisabledState;
  
}

// Hide or show the co-borrower fields depending on whether the co-borrower is enabled
// Takes no events
function toggleCoBorrower() {
  
  var doShow = fieldValue('LoanApplication_coborrower') == 'yes';

  for (var x=0; x<coBorrowerElements.length; x++) {
    coBorrowerElements[x].style.visibility = doShow ? 'visible' : 'hidden';
  }
  
}

// Disable/Enable the co-address depending on whether it is the same as the main borrower
// Takes no arguments
function toggleCoAddressDisabledState() {

  var doShow = document.getElementById('LoanApplication_sameasmain').checked == true;
  var togglingElements = new Array('LoanApplication_coaddressstreet', 'LoanApplication_coaddresssuburb', 'LoanApplication_coaddresscity', 'LoanApplication_coaddresshowlong', 'LoanApplication_copropertystatus', 'LoanApplication_copropertyexpense', 'LoanApplication_copropertyexpenseperiod_week', 'LoanApplication_copropertyexpenseperiod_fortnight', 'LoanApplication_copropertyexpenseperiod_month');
  
  var el;
  for (var elId in togglingElements) {
  
    el = document.getElementById(togglingElements[elId]);
  
    if (doShow) {
      if (el.type == 'radio')
        el.checked = false;
      else if (el.type.indexOf('select') > -1)
        el.selectedIndex = 0;
      else
        el.value = '';
    }
    document.getElementById(togglingElements[elId]).disabled = doShow;
  }

}

// Runs when form is submitted.
// Returns boolean. Form will not submit if this function returns false
// Takes no arguments
	function checkForm() {

  var validationStatus = true;
  validationMessages = new Array(0);
  
  var currentErrorLabels = getElementsByClassName('hasError');
  for (var x=0; x<currentErrorLabels.length; x++) removeClass(currentErrorLabels[x], 'hasError');

  if (false == validateRequiredFields()) validationStatus = false;
  if ( false == checkContactFields() ) validationStatus = false;
  if (false == validateValidFields()) validationStatus = false;
  
  if (false == validateLinkedFields()) validationStatus = false;
  
  if (false == validationStatus) {
    alertValidationMessages(); // Alternatively displayValidationInForm();
  }
  
  return validationStatus;

}


// Dislpay the form error messages in an alert popup
// Takes no arguments
function alertValidationMessages() {
  alert(validationMessages.join('\n'));
}

// Display the form error messages in an ordered list at the top of the page
// Takes no arguments
function displayValidationInForm() {

  document.getElementById('messages').innerHTML = '';

  var errorContainer = document.createElement('div');
  document.getElementById('messages').appendChild(errorContainer);
  
  var errorList = document.createElement('ol');
  errorContainer.appendChild(errorList);
  
  var errorListItem;
  for (var x in validationMessages) {
    errorListItem = document.createElement('li');
    errorListItem.innerHTML = validationMessages[x];
    errorList.appendChild(errorListItem);
  }
  
  location.href = '#top';
  
}

// Checks form fields are entered if they are required - based on the validation object
// Takes no arguments
// Returns boolean whether validation fails or not
function validateRequiredFields() {

  for (var fieldId in validation.required) {
    
    var elementLabel = getElementLabel(fieldId);
    if (isBlank(fieldId)) {
      validationMessages.push(validation.required[fieldId]);
      if (elementLabel) addClass(elementLabel, 'hasError');
    }
    
  }
  
  return validationMessages.length == 0;

}

// Checks form fields contain valid values - based on the validation object
// Takes no arguments
// Returns boolean whether validation fails or not
function validateValidFields() {

  var reg;

  for (var fieldId in validation.valid) {
  
  var elementLabel = getElementLabel(fieldId);
    reg = validation.valid[fieldId].format;
    
    if (false == reg.test(fieldValue(fieldId))) {
      validationMessages.push(validation.valid[fieldId].message);
      if (elementLabel)
      {
      	addClass(elementLabel, 'hasError');
   		if( document.getElementById(fieldId).name == 'LoanApplication_dob')
  		{	alertDOB();
  		}
      }
      
      
    }
       
  }
    
  return validationMessages.length == 0;

}

function alertDOB()
{
	var dob = document.getElementById('doblabel');
	dob.className += ' hasError';
	return true;
}

// Checks form fields are entered if they are required and linked to another field - based on the validation object
// Takes no arguments
// Returns boolean whether validation fails or not
function validateLinkedFields() {

  for (var fieldId in validation.requiredLink) {
      
    var elementLabel = getElementLabel(fieldId);
  
    if (typeof validation.requiredLink[fieldId].depends == 'object') {
    
      var result = new Array(0);
      
      for (var x=0; x<validation.requiredLink[fieldId].depends.length; x++) {
    
        if (fieldValue(validation.requiredLink[fieldId].depends[x].field) == validation.requiredLink[fieldId].depends[x].value) {
          result.push(true);
        }
        
      }
      
      if (result.length == validation.requiredLink[fieldId].depends.length && isBlank(fieldId)) {
        validationMessages.push(validation.requiredLink[fieldId].message);
        if (elementLabel) addClass(elementLabel, 'hasError');
      }
    
    } else {
    
      if (fieldValue(validation.requiredLink[fieldId].depends) == validation.requiredLink[fieldId].value && isBlank(fieldId)) {
        validationMessages.push(validation.requiredLink[fieldId].message);
        if (elementLabel) addClass(elementLabel, 'hasError');
      }
      
    }
    
  }
  
  return validationMessages.length == 0;
  
}

// Returns boolean whether the trimmed value of a field is blank
function isBlank(fieldId) {
  return fieldValue(fieldId) == '';
}

// Retrieves the value of a field
// Takes one String argument - the ID/Name of a field
// Returns:
//    String if field is text based or radio
//    boolean if field is checkbox
function fieldValue(fieldId) {

  var elements = document.getElementsByName(fieldId);

  if (elements.length && elements.length > 1) {
    for (var x=0; x<elements.length; x++) {
      if (true == elements[x].checked) return elements[x].value;
    }
    
  } else {
    if (document.getElementById(fieldId).type == 'checkbox')
      return document.getElementById(fieldId).checked == true;
    else
      return document.getElementById(fieldId).value.trim();
  
  }

  return false;
  
}

// Trims whitespace from the beginning/end of a string.
// Takes no arguments
// Returns String with whitespace removed from beginning/end
String.prototype.trim = function () {
  return this.replace(/^\s*/, "").replace(/\s*$/, "");
}

function getElementLabel(fieldId) {

  var elements = document.getElementsByName(fieldId);
  
  if (elements.length && elements.length > 1) el = document.getElementsByName(fieldId)[0];
  else el = document.getElementById(fieldId);
  
  while (el.parentNode) {
    el = el.parentNode;
    if (el.className == 'formRow') break;
  }
  
  var defaultLabel;
  var labels = el.getElementsByTagName('label');
  for (var x=0; x<labels.length; x++) {
    if (labels[x].getAttribute('for') == fieldId) return labels[x];
    if (labels[x].className.indexOf('mainLabel') > -1 && labels[x].innerHTML != '&nbsp;') defaultLabel = labels[x];
  }
  
  return defaultLabel;

}

function addClass(el, clsName) {
  el.className += ' ' + clsName;
  
}

function removeClass(el, clsName) {
  el.className = el.className.replace(clsName, '');
}

function checkContactFields()
{
	if ( fieldValue('LoanApplication_coborrower') == 'yes' )
	{
		if ( document.getElementById( 'LoanApplication_cobestcontact' ).value.trim() == 'Home' )
			cocontactfields = {  LoanApplication_cohomephone: 'Please enter the home number for the co-borrower.' };
		else if ( document.getElementById( 'LoanApplication_cobestcontact' ).value.trim() == 'Work' )
		{
			
			cocontactfields = {  LoanApplication_coworkphone: 'Please enter the work number for the co-borrower.' };
		}
		else if ( document.getElementById( 'LoanApplication_cobestcontact' ).value.trim() == 'Mobile' )
			cocontactfields = {  LoanApplication_comobile: 'Please enter the mobile number for the co-borrower.' };
	}

	if ( document.getElementById( 'LoanApplication_bestcontact' ).value.trim() == 'Home' )
		contactfields = {  LoanApplication_homephone: 'Please enter the home number for the main borrower.' };
	else if ( document.getElementById( 'LoanApplication_bestcontact' ).value.trim() == 'Work' )
		contactfields = {  LoanApplication_workphone: 'Please enter the work number for the main borrower.' };
	else if ( document.getElementById( 'LoanApplication_bestcontact' ).value.trim() == 'Mobile' )
		contactfields = {  LoanApplication_mobile: 'Please enter the mobile number for the main borrower.' };
  validateContactFields();
}

function validateContactFields() {

  for (var fieldId in contactfields )
  {
    var elementLabel = getElementLabel(fieldId);
    if (isBlank(fieldId))
    {
        validationMessages.push(contactfields[fieldId]);
      if (elementLabel) addClass(elementLabel, 'hasError');
    }
    
  }
  
   for (var fieldId in cocontactfields )
   {
     var elementLabel = getElementLabel(fieldId);
    if (isBlank(fieldId))
    {
       validationMessages.push(cocontactfields[fieldId]);
      if (elementLabel) addClass(elementLabel, 'hasError');
    }
    
  }
   return validationMessages.length == 0;

}

function validateCoDOBField()
{

  var reg;

  for (var fieldId in validation.coDOB)
  {
   		reg = validation.valid[fieldId].format;
    
    	if (false == reg.test(fieldValue(fieldId)))
    	{
      		validationMessages.push(validation.valid[fieldId].message);
      		var dob = document.getElementById('codoblabel');
			dob.className += ' hasError';
      	
      
     	}
       
  }
    
  return validationMessages.length == 0;

}

