var autoIncrement = 1000;
var multiPartProductsAllowedInputId = 'multipartProductsAllowed';
var PRODUCT_LIST_ID = 'productList';
var PRODUCT_CODE_ID = 'productCode';
var PRODUCT_OPTION_NAME_ID = 'productOptionName';
var PRODUCT_OPTION_CODE_ID = 'productOptionCode';
var LOAN_PART_ID = 'loanPart';
var REPAYMENT_TYPE_ID = 'repaymentType';
var lblProductDescriptionId = 'lblProduct';
var lblProductCodeErrorId = 'lblProductCodeError';
var SHOULD_VALIDATE_POSTCODE = 'shouldValidateId';
var PERFORM_MANDATORY_VALIDATION = 'performMandatoryValidation';
var CONTROL_TO_VALIDATE = 'controltovalidate';
var CONDITION_FIELD = 'conditionfield';
var creditCheckConfirmed = false;
var performAutomaticSubmission = false;

function confirmIfValidated(url)
{
	if (typeof(Page_ClientValidate) == 'function') 
	{
		if(Page_ClientValidate() == false)
		{			
			alert('You have not yet completed all the required information.\r\nPlease revisit the form and complete all mandatory fields.');
			return false;
		}
		else
		{		  
		    if (!creditCheckConfirmed)
		    {  
				var openWindow = window.open(url, 'creditCheckConfirmation', 'toolbar=no, height=550, width=680, left=' + (screen.width/2 - 350)
					+ ', top=' + (screen.height/2 - 300) + 'resizable=no, scrollbars=yes', false);
			    openWindow.focus();
		        return false;
		    }
		    else
		    {
		        return true;
		    }
		}
	}
}

function checkValidWithoutConfirmation()
{
	var isValid = Page_ClientValidate();
	if(isValid == false)
	{			
		alert('You have not yet completed all the required information.\r\nPlease revisit the form and complete all mandatory fields.');
	}
	return isValid;
}
/**
 * Proceeds with submitting the aip.
 * If the main page has been closed or the submission has already been confirmed 
 * it will simply close the window
 */
function submissionConfirmed()
{ 
	if (typeof(window.opener.creditCheckConfirmed) == 'undefined')
	{
		window.close();
		return;
	}
	if (window.opener.creditCheckConfirmed)
	{
		window.close();
		return;			
	}
	window.opener.creditCheckConfirmed = true;
	window.opener.document.all['master_body_submitAIP'].click();
	window.opener.document.all['master_body_submitAIP'].focus();
	window.close();
}

function clickSubmitAip()
{
	if (performAutomaticSubmission == true)
	{
		performAutomaticSubmission = false;
		document.all['master_body_submitAIP'].click();
	}
}

/**
 * Validates that a product was selected or a product code was entered
 */
function validateProductRequired()
{
    var loanPart = findElementAncestorLike(this, LOAN_PART_ID);
    var productList = findElementLikeRecursively(loanPart, PRODUCT_LIST_ID);
    var productCode = findElementLikeRecursively(loanPart, PRODUCT_CODE_ID);
    var productOptionName = findElementLikeRecursively(loanPart, PRODUCT_OPTION_NAME_ID);
    var productOptionCode = findElementLikeRecursively(loanPart, PRODUCT_OPTION_CODE_ID);
    
    if ((productList.selectedIndex != 0) && (productOptionName.checked)) 
    {
        return true;
    }
    if ((productCode.value != '') && (productOptionCode.checked)) 
    {
        return true;
    }
    //this happens if no multipart products are allowed.
    if (productList.disabled && productCode.disabled)
    {
        return true;
    }    
    
    return false;
}

function customMultipleSelectionValidationFunction(val)
{
    var fieldsToCheck;
    if (typeof val.controlstocheck == "undefined")
    {
	    fieldsToCheck = val.attributes[1].value.split(',');
	}
	else
	{
	    fieldsToCheck = val.controlstocheck.split(',');
	}
	return isAtLeastOneCheckboxChecked(document.body, fieldsToCheck);
}
/**
 * Enables/Disable the valuation fee field.
 * @dprFeeHiddenInputId whether the hidden input containing the fee value. Empty if no fee value needs to be set
 */
function enableValuationValueField(sectionId, enable, dprFeeHiddenInputId)
{
  var valuationFee = findElementLikeRecursively(sectionObjects[sectionId].getContent(), 'ValuationFeeValue');
  var updateFeesHiddenFlag = findElementLikeRecursively(sectionObjects[sectionId].getContent(), 'updateFeesFlag');
  
  valuationFee.disabled = !enable;
  if (dprFeeHiddenInputId == '')
  {
      valuationFee.value = '';
  }
  else
  {
      var feesSection = sectionObjects[getSectionIndex('fees')];
      var dprFeeHiddenInput = findElementLikeRecursively(feesSection.getContent(), dprFeeHiddenInputId);
      valuationFee.value = dprFeeHiddenInput.value;
  }
}

function conditionalDisplay(controllingFieldName, fields)
{
	conditionalController(controllingFieldName, fields, 'visibility');
}

function conditionalEnable(controllingFieldName, fields)
{
	conditionalController(controllingFieldName, fields, 'enabling');
}

function conditionalController(controllingFieldName, fields, controllerType)
{
    var start = new Date();
	var noOfFields = fields.length;
	var controllingFieldValue = GetElementValue(controllingFieldName);
	
	for(i = 0; i < noOfFields; i++)
	{
		var fieldName = fields[i][0];

		SetVisualProperty(controllerType, fieldName, false);
		
		for(j = 1; j < fields[i].length; j++)
		{
			if (checkDisplayCondition(fields[i][j], controllingFieldValue))
			{
				SetVisualProperty(controllerType, fieldName, true);	
				break;
			}
		}
	}
	var stop = new Date();
//	alert(stop.getTime() - start.getTime());
}

/**
 * Checks the given display condition against the given field value.
 * - condition represents a string that could have the following values: *; [any string]; gt0
 * - fieldValue represents a value of an aspx form's field.
 */
function checkDisplayCondition(condition, fieldValue)
{
	if ((condition == '*' && fieldValue.length > 0 && fieldValue != '')
		|| (condition == fieldValue)
		|| (condition == 'gt0' && fieldValue > 0))
	{
		return true;
	}
	
	return false;
}

/**
 * Displays or hides some fields and sections based on the value of the customer type field
 */
function customerTypeConditionalSectionDisplay()
{
    var values = new Array();
    var applicantDetailsSection = sectionObjects[getSectionIndex('applicantDetails')];
    findAllElementsLikeRecursively(applicantDetailsSection.getContent(), 'customerType', values);
    
    var sectionIndex = getSectionIndex('outgoingSection');
	var section = sectionObjects[sectionIndex];
	var groupOfElements = findElementLikeRecursively(section.getContent(), 'applicantExistingMortgages');
    
    var noOfApplicants = findElementLikeRecursively(sectionObjects[1].getContent(), 
        'numberOfApplicants');

    if (((values[0].value == 'F') && (noOfApplicants.value == 1)) 
        || ((noOfApplicants.value >= 2) && (values[0].value == 'F') && (values[1].value == 'F')))
    {    
        groupOfElements.style.display = 'none';
    } 
    else 
    {
        groupOfElements.style.display = 'block';
        showHideAllCellsById(groupOfElements, 'Odd', (values[0].value != 'F'));    
        var isSecondApplicantBTL = ((noOfApplicants.value >= 2) && (values[1].value != 'F'));
        showHideAllCellsById(groupOfElements, 'Even', isSecondApplicantBTL); 
    }    
    var customerTypeLists = new Array();
    var applicantDetailsSection = sectionObjects[getSectionIndex('applicantDetails')];
    
	findAllElementsLikeRecursively(applicantDetailsSection.getContent(), 
	    'customerType', customerTypeLists);
	conditionalSectionDisplay(customerTypeLists, 'additionalBorrowing', new Array('R'), 'or');
	conditionalSectionDisplay(customerTypeLists, 'depositFunding', new Array('F', 'M', 'G', 'P', 'Please Select'), 'and');
}

function conditionalDualControlDisplay()
{
    var incomeSection = sectionObjects[getSectionIndex('incomeSection')];
	var ctrl1 = findElementLikeRecursively(incomeSection.getContent(), 'EmploymentStatusOdd');
	var ctrl2 = findElementLikeRecursively(incomeSection.getContent(), 'EmploymentStatusEven');

	var isBtl = findElementLikeRecursively(sectionObjects[1].getContent(), 'isBtlLoanType');
	
	setFieldVisibilityByDualQuick(incomeSection.getContent(), 'EmploymentTypeRow', ctrl1.value, ctrl2.value, new Array('E'));
	setFieldVisibilityByDualQuick(incomeSection.getContent(), 'currentOccupationRow', ctrl1.value, ctrl2.value, new Array('E', 'S'));

	if (isBtl.value == 'False')
	{
		setFieldVisibilityByDualQuick(incomeSection.getContent(), 'AnualBasicSalaryRow', ctrl1.value, ctrl2.value, new Array('E'));
		setFieldVisibilityByDualQuick(incomeSection.getContent(), 'UKTaxableIncomeRow', ctrl1.value, ctrl2.value, new Array('S'));
		setFieldVisibilityByDualQuick(incomeSection.getContent(), 'PreviousTaxableIncomeRow', ctrl1.value, ctrl2.value, new Array('S'));
		var isSelfCert = findElementLikeRecursively(sectionObjects[1].getContent(), 'isSelfCert');
		if (isSelfCert.value == 'False')
		{
		    setFieldVisibilityByDualQuick(incomeSection.getContent(), 'NonGuaranteedBonusRow', ctrl1.value, ctrl2.value, new Array('E'));
		    setFieldVisibilityByDualQuick(incomeSection.getContent(), 'AnualBasicPensionRow', ctrl1.value, ctrl2.value, new Array('R'));
		    setFieldVisibilityByDualQuick(incomeSection.getContent(), 'OtherRegularIncomeRow', ctrl1.value, ctrl2.value, new Array('E', 'R', 'U'));
		}
	}
}
/**
 * Controls a field's visibility using two controls
 */
function setFieldVisibilityByDual(fieldName, controllingFieldValue1, controllingFieldValue2, visibleValues)
{
	setFieldVisibilityByDualQuick(document.body, fieldName, controllingFieldValue1, controllingFieldValue2, visibleValues)
}
/**
 * Controls a field's visibility using two controls
 * If any of the two controls has a value contained in the list of 'visible values'
 * the controlled field will be shown
 */
function setFieldVisibilityByDualQuick(parentElement, fieldName, controllingFieldValue1, 
    controllingFieldValue2, visibleValues)
{
	var controlledField = findElementLikeRecursively(parentElement, fieldName);
	var count = visibleValues.length;
	
	if (controlledField == null)
	{
		return;
	}

	SetVisualProperty('visibility', controlledField.id, false);

	for(i = 0; i < count; i++)
	{
		var visibleValue = visibleValues[i];
		
		if (checkDisplayCondition(visibleValue, controllingFieldValue1)
			|| checkDisplayCondition(visibleValue, controllingFieldValue2))
		{
			SetVisualProperty('visibility', controlledField.id, true);
			break;
		}
	}
}

function conditionalSectionDisplay(controllingFields, sectionName, fieldValues, condition)
{	
	var noOfApplicants = findElementLikeRecursively(sectionObjects[1].getContent(), 'numberOfApplicants');
	
	if ((noOfApplicants.value == 1) && (controllingFields.length >= 1))
	{
		var condition = checkElementValue(controllingFields[0].id, fieldValues);
		Section.setVisibility(sectionName, condition);
		return;
	}
	if ((noOfApplicants.value >= 1) && (controllingFields.length > 1))
	{
		var condition1 = checkElementValue(controllingFields[0].id, fieldValues);
		var condition2 = checkElementValue(controllingFields[1].id, fieldValues);
		var finalCondition = (condition == 'or') ? (condition1 || condition2) : (condition1 && condition2);
		Section.setVisibility(sectionName, finalCondition);
	}
}

function btlConditionalSectionDisplay()
{
//    start = new Date();
	var isBtl = findElementLikeRecursively(sectionObjects[1].getContent(), 'isBtlLoanType');
	var outgoingSection = sectionObjects[getSectionIndex('outgoingSection')];
	
	var otherBTL = findElementLikeRecursively(outgoingSection.getContent(), 'otherBTLRow');
	var monthlyRental = findElementLikeRecursively(outgoingSection.getContent(), 'monthlyRentalValueRow');
	
	otherBTL.style.display = (isBtl.value == 'True') ? 'block' : 'none';
	monthlyRental.style.display = (isBtl.value == 'True') ? 'block' : 'none';	
	return isBtl;
}
/**
 * Hides some divs when a self cert product is selected
*/
function selfCertConditionalSectionDisplay()
{
    var isSelfCert = findElementLikeRecursively(sectionObjects[1].getContent(), 'isSelfCert');
	if (isSelfCert.value == 'True')
	{
	    var incomeSection = sectionObjects[getSectionIndex('incomeSection')];
	    
	    var nonGuaranteedBonusRow = findElementLikeRecursively(incomeSection.getContent(), 'NonGuaranteedBonusRow');
	    nonGuaranteedBonusRow.style.display = 'none';
	    
	    var anualBasicPensionRow = findElementLikeRecursively(incomeSection.getContent(), 'AnualBasicPensionRow');
	    anualBasicPensionRow.style.display = 'none';
	    
	    var otherRegularIncomeRow = findElementLikeRecursively(incomeSection.getContent(), 'OtherRegularIncomeRow');
	    otherRegularIncomeRow.style.display = 'none';
	}
}

function calculateArrangementFee()
{
	var totalLoanAmount = 0;
	var loanAmountFields = new Array();
	
	findAllElementsLikeRecursively(sectionObjects[1].getContent(), 'loanAmount', loanAmountFields);
	
	for(i = 0; i < loanAmountFields.length; i++)
	{
		var loanAmountNumber = parseInt(loanAmountFields[i].value);
		if (!isNaN(loanAmountNumber))
		{
			totalLoanAmount += loanAmountNumber;
		}
	}
	
	var percent = findElementLikeRecursively(document.body, 'LblArrangementFeePercentValue');
	var arrangementFee = findElementLikeRecursively(document.body, 'ArrangementFeeValue');
	
	if (!isNaN(loanAmountNumber) && (arrangementFee != null) && (percent != null))
	{
		var arrangementFeeNumber = totalLoanAmount * parseFloat(percent.innerHTML) / 100;
		if (!isNaN(arrangementFeeNumber))
		{
			arrangementFee.value = arrangementFeeNumber;
		}
	}
}


/**
 * Shows or hides the part in section 6 that relates to 
 * the initial deposit required for the loan.
 */
function initialDepositDisplay()
{
    var isHundredPercent = findElementLikeRecursively(sectionObjects[1].getContent(), 'isHundredPercentProduct');
    var depositSection = sectionObjects[getSectionIndex('depositFunding')];
    
    var depositPart = findElementLikeRecursively(depositSection.getContent(), 'depositInformation');
    if (isHundredPercent.value == 'True')
    {
        depositPart.style.display = 'none';    
        removeValidators(depositPart);
    }
    else
    {
        depositPart.style.display = 'block';
        reactivateValidators(depositPart);
    }
}
function checkElementValue(fieldName, fieldValues)
{
	var value = GetElementValue(fieldName);
	for(i = 0; i < fieldValues.length; i++)
	{
		if ((fieldValues[i] == '*') && (value.length > 0) && (value != ''))
		{
			return true;		
		}
		if (value == fieldValues[i])
		{
			return true;
		}
	}
	return false;
}

function GetElementValue(fieldID)
{
	var element = document.getElementById(fieldID);
	if (element.type == 'checkbox')
	{
		return element.checked ? 'true' : 'false';
	}
	else
	{
		return element.value;
	}
}

function SetVisualProperty(controllerType, fieldName, isPropertyEnabled)
{
	if (document.getElementById(fieldName) == null)
	{
		return;
	}
	
	if (controllerType == 'visibility')
	{
		document.getElementById(fieldName).style.display = isPropertyEnabled ? 'block' : 'none';
	}
	if (controllerType == 'enabling')
	{
		document.getElementById(fieldName).disabled = !isPropertyEnabled;
	}	
}

function customVisibilityByCheckList(fieldName, fieldToClear, controllingFieldNames)
{
    var depositSection = sectionObjects[getSectionIndex('depositFunding')];
	var isAtLeastOneChecked = isAtLeastOneCheckboxChecked(depositSection.getContent(), 
	    controllingFieldNames);
	
	var field = findElementLikeRecursively(depositSection.getContent(), fieldName);
	SetVisualProperty('visibility', field.id, isAtLeastOneChecked);
	
	if (!isAtLeastOneChecked)
	{
		var elem = findElementLikeRecursively(depositSection.getContent(), fieldToClear);
		if (elem != null)
		{
			elem.value = '';
		}
	}
}

function isAtLeastOneCheckboxChecked(parentElement, controllingFieldNames)
{
	for(i = 0; i < controllingFieldNames.length; i++)
	{
		var ctrlField = findElementLikeRecursively(parentElement, controllingFieldNames[i]);
		
		if (ctrlField.checked)
		{
			return true;
			break;
		}
	}
	return false;
}

/**
 * Duplicates the contents of a div.
 * Returns the cloned node
 */
function duplicateByElementName(elementName)
{
	//alert('duplicateByElementName::enter');
	var element = document.getElementById(elementName);
	return duplicateByElementRef(element);
}
/**
 * Duplicates the contents of a div.
 * This overload takes as parameter a reference to an element,
 * Returns the cloned node.
 */
function duplicateByElementRef(element)
{
	
	var clone = duplicateByRefDoNotInsert(element);
	//alert('duplicated element' + clone);
	element.parentElement.insertAdjacentElement('beforeEnd', clone);
	
	return clone;
}
/**
 * Also hooks-up the newly added validators with the newly added control
 */
function updateNewlyAddedValidators(previousValidatorCount)
{
	for (var i = previousValidatorCount; i < Page_Validators.length; i++)
	{
	    ValidatorHookupControlID(Page_Validators[i].getAttribute(CONTROL_TO_VALIDATE), 
	        Page_Validators[i]);
	}
}
/**
 * Duplicates an element without inserting it into the DOM tree.
 */
function duplicateByRefDoNotInsert(element)
{
	var clone = element.cloneNode(true);
	
	//alert('updating clone with ctl' + autoIncrement);
	autoIncrement = autoIncrement + 1;
	updateRepeatedControls(clone, 'ctl' + autoIncrement, element);
	return clone;
}
/**
 * Duplicates an existing element and shows the delete button for it.
 * Also verifies that the add button is not displayed anymore
 */
function duplicateAndShowDeleteButton(addButtonName, section, elementName, 
	deleteButtonName, maxPartAnPartEntriesInputId)
{
    var prevValidatorsCount = Page_Validators.length;
    var element = document.getElementById(elementName);
    var cloned = duplicateByRefDoNotInsert(element);
	element.parentElement.insertAdjacentElement('beforeEnd', cloned);
    
    
	var deleteButton = findElementRecursively(cloned, deleteButtonName);
	var addButton = findElementRecursively(cloned, addButtonName);
	deleteButton.getAttribute('style').setAttribute('visibility', 'visible');
	updateAddLoanPartButtonVisibility(deleteButtonName, addButtonName, section, maxPartAnPartEntriesInputId);
	updateProductField(cloned, prevValidatorsCount);
	
	var multiPartProductsAllowedInput = findElementLikeRecursively(sectionObjects[1].getContent(), 
	    multiPartProductsAllowedInputId);

	if (multiPartProductsAllowedInput.value == 'False')
	{
	  var divLoanTerm = findElementLikeRecursively(cloned, 'loanTermId');
	  divLoanTerm.style.display = 'none';
	}
	
	var interestWarningLabel = findElementLikeRecursively(cloned, 'interestWarning');
	interestWarningLabel.style.display = 'none';
}
/**
 * Updates the visibility of the Add Loan Part button
 */
function updateAddLoanPartButtonVisibility(deleteButtonName, addButtonName, section, maxPartAnPartEntriesInputId)
{
	var sectionIndex = getSectionIndex(section);
	var section = sectionObjects[sectionIndex];
	var products = new Array();
	findAllElementsLikeRecursively(section.getContent(), deleteButtonName, products);
	var maxPartAndPartEntriesInput = findElementLikeRecursively(section.getContent(), maxPartAnPartEntriesInputId);
	var addButton = findElementLikeRecursively(section.getContent(), addButtonName);
	
	if (products.length < maxPartAndPartEntriesInput.value)
	{
		addButton.getAttribute('style').setAttribute('visibility', 'visible');
	}
	else
	{
		addButton.getAttribute('style').setAttribute('visibility', 'hidden');
	}
}
/**
 * Disables the product list, the product code textbox
 * and the product option radiobuttons for an additional loan part
 * if no multiple part and part products are allowed.
 */
function updateProductField(loanPartDiv, prevValidatorsCount)
{
	var multiPartProductsAllowedInput = findElementLikeRecursively(sectionObjects[1].getContent(), 
	    multiPartProductsAllowedInputId);
	//alert(multiPartProductsAllowedInput.value);
	var productList = findElementLikeRecursively(loanPartDiv, PRODUCT_LIST_ID);
	var productCode = findElementLikeRecursively(loanPartDiv, PRODUCT_CODE_ID);
    var productOptionCode = findElementLikeRecursively(loanPartDiv, PRODUCT_OPTION_CODE_ID);
    var productOptionName = findElementLikeRecursively(loanPartDiv, PRODUCT_OPTION_NAME_ID);
    var repaymentList = findElementLikeRecursively(loanPartDiv, REPAYMENT_TYPE_ID);
	
    productOptionCode.checked = false;
    
	if (multiPartProductsAllowedInput.value == 'False')
	{
	    productOptionName.checked = false;
		var lblProductCodeError = findElementLikeRecursively(loanPartDiv, lblProductCodeErrorId);
						
		productList.disabled = 'true';
		productCode.disabled = 'true';
		productOptionName.onclick = null;
		productOptionCode.onclick = null;
		if (lblProductCodeError != null) 
		{
			lblProductCodeError.innerHTML = '';
		}
		
		productOptionName.disabled = true;
		productOptionCode.disabled = true;
	}
	else
	{
	    productOptionName.checked = true;
	    var lblProductDescription = findElementLikeRecursively(loanPartDiv, lblProductDescriptionId);
	    if (lblProductDescription != null)
	    {
	        lblProductDescription.innerHTML = '';    
	    }
	    
	    var toBeEvaluated = productList.onchange.toString();
	    var lineStartIndex = toBeEvaluated.lastIndexOf('__doPostBack');
	    var lineEndIndex = toBeEvaluated.indexOf(')', lineStartIndex);
	    
        toBeEvaluated = toBeEvaluated.substring(0, lineStartIndex) + 
            toBeEvaluated.substring(lineEndIndex + 1, toBeEvaluated.length);
	    eval('productList.onchange = ' + toBeEvaluated);
	    productCode.value = '';
	    productList.selectedIndex = 0;	    
	    productList.disabled = false;
	}
	updateNewlyAddedValidators(prevValidatorsCount);
	repaymentList.selectedIndex = 0;
}
/**
 * Removes a section and its validators
 */
function removeSection(section)
{
	//alert('removing node ' + i + ' ' + elements[i]);
	for (var vIndex = 0; vIndex < Page_Validators.length; vIndex++)
	{
		if (isAncestor(Page_Validators[vIndex], section) == true)
		{
			//alert('Removing validator ' + Page_Validators[vIndex].id)
			Page_Validators.splice(vIndex, 1);
			vIndex--;
		}
	}
	section.removeNode(true);
}
/**
 * Removes a product part.
 * Also removes the validators from within that part.
 * Also makes sure that the add loan part button becomes visible.
 */
function removePart(element, addButtonName, section, maxPartAnPartEntriesInputId)
{
	//alert('remove:enter elementId=' + element);
	var element = element.parentElement.parentElement;
	if (element.tagName == 'DIV')
	{
	    removeValidators(element);
		element.removeNode(true);		
//		alert(element.id);
	}
	updateAddLoanPartButtonVisibility(element.id, addButtonName, section, maxPartAnPartEntriesInputId);
}
/**
 * Updates the repeated controls' names, ids, onchange event handlers 
 * controlToValidate attribute,
 * and includes the validators in the page validators array.
 * Note that validators still need to be hooked up with their controls
 */
function updateRepeatedControls(clone, value, original)
{
	//alert('updatedRepeatedControls::enter');
	
	var kids = clone.children;
	var noOfKids = kids.length;
	for (var i = 0; i < noOfKids; i++)
	{
		if (kids[i].id.search('ctl'))
		{			
			var validatorIndex = findElementInArray(kids[i], Page_Validators);	
			if (kids[i].tagName == 'SELECT')
			{
                var archetype = findElementRecursively(original, kids[i].id);			        
                if (archetype != null)
                {
                    kids[i].outerHTML = archetype.outerHTML.replace(/ctl/g, value);
                    if(archetype.onchange != null)
                    {
                        eval('kids[i].onchange = ' + 
                            archetype.getAttribute('onchange').toString().replace(/ctl/g, value));
                    }
                }
                kids[i].selectedIndex = -1;
			}			
			/*else if (kids[i].tagName == 'SELECT' && kids[i].getAttribute('onchange') != null)
			{
				kids[i].outerHTML = kids[i].outerHTML.replace(/ctl/g, value);
			}*/
			else if (kids[i].tagName == 'INPUT')
			{
				kids[i].outerHTML = kids[i].outerHTML.replace(/ctl/g, value);
				if (kids[i].type == 'text')
				{
					if (kids[i].value != 'dd/mm/yyyy')
					{
						kids[i].value = '';
					}
				}
			}
			else if (kids[i].tagName == 'LABEL')
			{
				kids[i].outerHTML = kids[i].outerHTML.replace(/ctl/g, value);				
			}
			else
			{				
				kids[i].id = kids[i].id.replace('ctl', value);
				if (kids[i].name != null)
				{					
					kids[i].name = kids[i].name.replace('ctl', value);
				}
			}
			if (validatorIndex != -1)
			{	
			    if (kids[i].getAttribute(CONTROL_TO_VALIDATE) != null)
			    {
                    kids[i].setAttribute(CONTROL_TO_VALIDATE, 
					    kids[i].getAttribute(CONTROL_TO_VALIDATE).replace('ctl', value));
				}	
				if (null != kids[i].getAttribute(CONDITION_FIELD))
				{
					kids[i].setAttribute(CONDITION_FIELD, 
						kids[i].getAttribute(CONDITION_FIELD).replace('ctl', value));
				}
				
				if (null != kids[i].getAttribute(SHOULD_VALIDATE_POSTCODE))
				{
				    kids[i].setAttribute(SHOULD_VALIDATE_POSTCODE, 
					    kids[i].getAttribute(SHOULD_VALIDATE_POSTCODE).replace('ctl', value));
				}
				
				Page_Validators.push(kids[i]);
			}
		} 
		updateRepeatedControls(kids[i], value, original);
	}
}

/**
 * Finds the first element in a hierarchical structure with a given id
 */
function findElementRecursively(root, elementId)
{
	if (typeof root.id != 'undefined')
    {
	    if (root.id == elementId) return root;
	    for (var i = 0; i < root.childNodes.length; i++)
	    {
		    var retVal = findElementLikeRecursively(root.childNodes[i], elementId)
		    if (retVal != null) return retVal;
	    }
	}
	return null;
}

/**
 * Finds the first element in a hierarchical structure that matches the given id
 */
function findElementLikeRecursively(root, elementId)
{
    if (typeof root.id != 'undefined')
    {
	    if (root.id.search(elementId) != -1) return root;
	    
	}
	if (typeof root.childNodes != 'undefined')
	{
	    for (var i = 0; i < root.childNodes.length; i++)
	    {
		    var retVal = findElementLikeRecursively(root.childNodes[i], elementId)
		    if (retVal != null) return retVal;
	    }
	}
	return null;
}

/**
 * Finds all elements in a hierarchical structure that matches the given name
 */
function findAllElementsLikeRecursivelyByName(root, elementName, results)
{
	if (root.name != null && root.name.search(elementName) != -1) 
	{
		results.push(root);
	}
	for (var i = 0; i < root.children.length; i++)
	{
		findAllElementsLikeRecursivelyByName(root.children[i], elementName, results)		
	}
}

/**
 * Finds all elements in a hierarchical structure that matches the given id
 */
function findAllElementsLikeRecursively(root, elementId, results)
{
	if (root.id.search(elementId) != -1)
	{
		results.push(root);
	}
	
	for (var i = 0; i < root.children.length; i++)
	{
		findAllElementsLikeRecursively(root.children[i], elementId, results)
	}
}

/**
 * Finds the index of the first element in an array of elements searching after its id.
 */
function findElementInArray(element, array)
{
	for (var i = 0; i < array.length; i++)
	{
//		    alert('found it! no of validators = ' + array.length);
		if (element.id == array[i].id) return i;		
	}
	return -1;
}

/**
 * Clears the selection/entered text for the no longer used productOption
 * If this is not the first product and
 */
function productOptionChanged(useCode, listElementId, codeElementId)
{	
	var listElement = findElementRecursively(sectionObjects[1].getContent(), listElementId);
	var codeElement = findElementRecursively(sectionObjects[1].getContent(), codeElementId);
		
	if (useCode)
	{
		listElement.selectedIndex = 0;
		listElement.disabled = true;
		codeElement.disabled = false;
	}
	else
	{
		codeElement.value = '';
		codeElement.disabled = true;
		listElement.disabled = false;
	}
	
}
/**
 * Opens the address finder popup and passes to it the fields
 * where information found there will be displayed.
 */
function findAddress(postCodeId, addressLine1Id, addressLine2Id, 
	addressLine3Id, countyId)
{
	var postCode = findElementRecursively(document.body, postCodeId).value;	
	var url = 'Shared/AddressPopup.aspx?postCode=' + postCode + '&line1=' + addressLine1Id + '&line2=' + addressLine2Id + '&line3=' + 
		addressLine3Id + '&county=' + countyId;
	window.open(url, '_blank', 'toolbar=no, height=160, width=340, left=' + (screen.width/2 - 110)
		+ ', top=' + (screen.height/2 - 75) + 'resizable=no, scrollbars=no', false);
}

/** 
 * Finds an element's ancestor
 */
function findElementAncestor(element, parentId)
{
	while (element.parentElement != null)
	{
		if (element.parentElement.id == parentId)
		{
			return element.parentElement;
		}
		element = element.parentElement;
	}
	return null;
}
/** 
 * Finds an element's ancestor
 */
function findElementAncestorLike(element, parentId)
{
	while (element.parentElement != null)
	{
		if (element.parentElement.id.search(parentId) != -1)
		{
			return element.parentElement;
		}
		element = element.parentElement;
	}
	return null;
}
/** 
 * Finds an element's ancestor
 */
function isAncestor(element, parent)
{
	while (element.parentElement != null)
	{
		if (element.parentElement == parent)
		{
			return true;
		}
		element = element.parentElement;
	}
	return false;
}

/**
 * Disables the validators outside of a given section.
 * Enables the validators inside the given section only if the controls to validate are enabled.
 */
function disableValidatorsOutsideOfSection(topSectionElement, applicantIndex)
{
	//alert('disableValidatorsOutsideOfSection' + topSectionElement.id + applicantParity + applicantIndex);
	
	for (var i = 0; i < Page_Validators.length; i++)
	{
		var parentSection = findElementAncestor(Page_Validators[i], topSectionElement.id);
		if (parentSection == null)
		{
			Page_Validators[i].enabled = false;
			continue;
		}
		else
		{
		    var controlToValidate = document.getElementById(Page_Validators[i].controltovalidate);
		    if (controlToValidate == null)
		    {
		       controlToValidate = document.getElementById(Page_Validators[i].checkBoxToValidate);
		    }
		    if (controlToValidate != null)
		    {
			    Page_Validators[i].enabled = !controlToValidate.disabled;    
            }
            else
            {
                Page_Validators[i].enabled = true;
            }
			//alert(Page_Validators[i].id);
		}
	}
}
/** 
 * Removes the validators from within an element.
 */
function removeValidators(element)
{
    for (var i = 0; i < element.children.length; i++)
    {
        var vIndex = findElementInArray(element.children[i], Page_Validators);
        if (vIndex != -1)
        {
            Page_Validators.splice(vIndex, 1);
        }
        else
        {
            removeValidators(element.children[i]);
        }
    }
}
/** 
 * Reactivates the validators from within an element.
 */
function reactivateValidators(element)
{
    for (var i = 0; i < element.children.length; i++)
    {
        if (element.children[i].getAttribute('controltovalidate') != null)
        {
			var notFound = true;
			for (var j = 0; j < Page_Validators.length; j++)
			{
				if (Page_Validators[j].id == element.children[i].id)
				{
					notFound = false;
					break;
				}
			}
			if (notFound)
			{
				Page_Validators.push(element.children[i]);
            }
        }
        else
        {
            reactivateValidators(element.children[i]);
        }
    }
}
/** 
 * Validates the entered postcode.
 */
function validatePostCode(validator)
{
    var postCodeBox = document.getElementById(validator.controltovalidate);
    
    if (!isVisible(postCodeBox)) return true;
    //if(postCodeBox.style.display == 'none')
      //return true;
    
    var ukPostCodeRadio = document.getElementById(validator.getAttribute(SHOULD_VALIDATE_POSTCODE));
    if (!ukPostCodeRadio.checked) return true;

	var mandatoryValidation = validator.getAttribute(PERFORM_MANDATORY_VALIDATION);
	if (mandatoryValidation == null)
		mandatoryValidation = 'True';
	if ((mandatoryValidation == 'False') && postCodeBox.value == '') return true;

    var codes = postCodeBox.value.split(' ');
    
    if (codes.length != 2)
    {
        if (postCodeBox.value.length < 5) return false;
        var secondIndex = postCodeBox.value.length - 3;
        codes = new Array(2);
        codes[1] = postCodeBox.value.substring(secondIndex, postCodeBox.value.length);
        codes[0] = postCodeBox.value.substring(0, secondIndex);
        //alert(codes[0]);
        //alert(codes[1]);
    }
    if (codes[1].length != 3) return false;
    if ((codes[0].length < 2) || (codes[0].length > 4)) return false;
    var alphaRegex = new RegExp('[A-Za-z]')
    var numericRegex = new RegExp('[0-9]');
    if (!codes[0].charAt(0).match(alphaRegex)) return false;
    if (!codes[1].charAt(0).match(numericRegex)) return false;
    if (!codes[1].charAt(1).match(alphaRegex)) return false;
    if (!codes[1].charAt(2).match(alphaRegex)) return false;
    return true;
}

/*
 * Returns a value indicating shether the control is visible.
 * A control might not be visible in case its parent is not visible.

 * ATT: Section content DIVs will always be considered visible !!!
 */
function isVisible(control)
{
	while (control != null)
	{
		if (control.style.display == 'none')
		{
			// Section content DIVs will be considered always visible
			if (isContentOfASection(control))
			{
				return true;
			}
			else
			{
				return false;
			}
		}
		
		control = control.parentElement;
	}
	
	return true;
}

function isVisibleNoSection(control)
{
	while (control != null)
	{
		if (control.style.display == "none")
		{
             return false
		}
		
		control = control.parentElement;
	}
	
	return true;
}

/*
 * Returns true if the control represents the content of a section.
 */
function isContentOfASection(control)
{
	if (control.id != null)
	{
		for (var i = 1; i < sectionObjects.length; i++)
		{
			if (control.id == sectionObjects[i].getContent().id)
			{
				return true;
			}
		}
	}

	return false;
}

/**
  * Shows a popup with the advisory note for the existing mortgage amount
  */
 function showExistingMortgageAdvisory()
 {
    var url = 'Shared/ExistingMortgageAdvisoryNote.htm';
	window.open(url, '_blank', 'toolbar=no, height=160, width=340, left=' + (screen.width/2 - 110)
		+ ', top=' + (screen.height/2 - 75) + 'resizable=no, scrollbars=no', false);
 }
 
/**
  * Shows a popup with the advisory note for the applicant
  */
 function showApplicantAdvisory()
 {
    var url = 'Shared/CreditWorthAdvisoryNote.htm';
	window.open(url, '_blank', 'toolbar=no, height=160, width=460, left=' + (screen.width/2 - 110)
		+ ', top=' + (screen.height/2 - 75) + 'resizable=no, scrollbars=no', false);
 }
/**
  * Shows a popup with an advisory note for the monthly outgoings field
  */
 function showOutgoingsAdvisory()
 {
    var url = 'Shared/OutgoingsAdvisoryNote.htm';
	window.open(url, '_blank', 'toolbar=no, height=160, width=240, left=' + (screen.width/2 - 110)
		+ ', top=' + (screen.height/2 - 75) + 'resizable=no, scrollbars=no', false);
 }
 
 function changeLandRegistryFee(location, feesSectionId)
 {
	var feesSectionContent = sectionObjects[getSectionIndex(feesSectionId)].getContent();

    var hiddenDprLandRegistryScotlandFeeValue = findElementLikeRecursively(feesSectionContent, 'hiddenDprLandRegistryScotlandFeeValue');
    var hiddenDprLandRegistryEnglandFeeValue = findElementLikeRecursively(feesSectionContent, 'hiddenDprLandRegistryEnglandFeeValue');
    var hiddenDprLandRegistryNIFeeValue = findElementLikeRecursively(feesSectionContent, 'hiddenDprLandRegistryNIFeeValue');
    var DivLandRegistryFee = findElementLikeRecursively(feesSectionContent, 'DivLandRegistryFee');
    var LandRegistryFeeValue = findElementLikeRecursively(feesSectionContent, 'LandRegistryFeeValue');
    
    // BAW - excluded
    if (LandRegistryFeeValue == null)
      return;
    
    if (location == 'Y' && hiddenDprLandRegistryScotlandFeeValue.value > 0)
    {
      LandRegistryFeeValue.value = hiddenDprLandRegistryScotlandFeeValue.value;
      DivLandRegistryFee.style.display = 'block';
    }
    else if (location == 'N' && hiddenDprLandRegistryEnglandFeeValue.value > 0)
    {
      LandRegistryFeeValue.value = hiddenDprLandRegistryEnglandFeeValue.value;
      DivLandRegistryFee.style.display = 'block';
    }
    else if (location == 'I' && hiddenDprLandRegistryNIFeeValue.value > 0)
    {
      LandRegistryFeeValue.value = hiddenDprLandRegistryNIFeeValue.value;
      DivLandRegistryFee.style.display = 'block';  
    }    
    else
    {
      DivLandRegistryFee.style.display = 'none';
    }
 }