//---------------------------------------------------------------------------------------------------------------------------------
// newValidation.js
//
// Validates the form in a page based on custom attributes in the HTML
//
// v1.0 JEB 29-10-02
// v1.1 30-10-02 Support for select boxes of type multiple
// v1.2 31-10-02 Support for 'creditcard' validation type for text boxes.
// v1.21 12-11-02 creditcard type now focuses on + selects card field if invalid
// v1.3 14-11-02 support for 'phone' type for textboxes.
// v1.4 21-11-02 parseQueryString() function added.
// v1.5 22-11-02 toggleValidation(anElement) added.
// v1.6 12-03-03 - RJL - Added optional argument to pass through the form to validate. Usage: onSubmit="return validateForm(this);"
// v1.7 01-07-03 - RJL - Don't toggleValidation if a null element (array) is passed in
//---------------------------------------------------------------------------------------------------------------------------------

function Msfg$getElementAttributeValue(element, attributeNames, defaultValue)
{
    var attributeNameCount = attributeNames.length;

    if (element.getAttribute == undefined)
    {
        for (var attributeNameIndex = 0; attributeNameIndex < attributeNameCount; attributeNameIndex++)
        {        
            var attributeName = attributeNames[attributeNameIndex];
            
            if (eval('element.' + attributeName) != undefined && eval('element.' + attributeName) != '')
            {
                return eval('element.' + attributeName);            
            }
        }
    }
    else
    {
        for (var attributeNameIndex = 0; attributeNameIndex < attributeNameCount; attributeNameIndex++)
        {        
            var attributeName = attributeNames[attributeNameIndex];
            
            if (element.getAttribute(attributeName) != undefined && element.getAttribute(attributeName) != '')
            {
                return element.getAttribute(attributeName);            
            }
        }
    }
    
    return defaultValue;
}

function Msfg$convertStringToBoolean(value, defaultValue)
{
    if ((typeof value) == 'string')    
    {
        var lowerCaseValue = value.toLowerCase();
    
        if (lowerCaseValue == 'true' || lowerCaseValue == 'yes')
        {
            return true;
        }
        else
        {
            return defaultValue;
        }
    }
    else
    {
        return defaultValue;
    }    
}

function Msfg$getElementAttributeValueAsBoolean(element, attributeNames, defaultValue)
{
    var valueString = Msfg$getElementAttributeValue(element, attributeNames, null);
    var valueBoolean = Msfg$convertStringToBoolean(valueString, defaultValue);
    return valueBoolean;
}

function validateForm(objForm)
{
 // Declare local variables.
 var currentElement;
 var needsValidation;

 //Check if a form has been specified - otherwise use the first form on the page
 if (arguments.length == 0) {
  frmForm = document.forms[0];
 } else {
  frmForm = objForm;
 }

 var isV6 = (frmForm.elements[0].getAttribute != null) ? true : false;
 var dfe = frmForm.elements;

 var pageIsValid = true;
 for (var f=0; f<dfe.length && pageIsValid == true; f++)
 {
  currentElement = dfe[f];
  
  isVisible = true;
  
  var parentElement = currentElement.parentNode;
  
  while (parentElement != undefined && parentElement.style != undefined)
  {
    if (parentElement.style.display == 'none')
    {
        isVisible = false;
        break;
    }   

    parentElement = parentElement.parentNode;
  }
  
  if (isVisible)
  {
      needsValidation = Msfg$getElementAttributeValueAsBoolean(currentElement, Array('msfg-validate', 'validate'), false);
      
      if (needsValidation)
      {
       var elementType = currentElement.type.toLowerCase();
       switch (elementType)
       { 
         case 'text':
         case 'textarea':
         case 'password':
            pageIsValid = (isV6) ?  checkTextBoxV6(currentElement.name) : checkTextBoxV5(currentElement.name);
            break;
        case 'radio' :
            pageIsValid = (isV6) ? checkRadioButtonsV6(currentElement.name) : checkRadioButtonsV5(currentElement.name);
            break;
        case 'checkbox' :
            pageIsValid = (isV6) ? checkCheckBoxV6(currentElement.name) : checkCheckBoxV5(currentElement.name);
            break;
        case 'select-one' :
            pageIsValid = (isV6) ? checkSelectV6(currentElement.name) : checkSelectV5(currentElement.name);
            break;
        case 'select-multiple' :
            pageIsValid = (isV6) ? checkSelectMultV6(currentElement.name) : checkSelectMultV5(currentElement.name);
            break;
       }
      }    
  }
 }

  return pageIsValid;
}

function checkTextBoxV5(aName)
{
 var dfe = frmForm.elements;
 var validationType = (dfe[aName].validationtype == null) ? "Alphanumeric" : dfe[aName].validationtype;
 var showmessage = (dfe[aName].showmessage != null) ? dfe[aName].showmessage.toLowerCase() : "yes";
 showmessage = ((showmessage == "yes") || (showmessage == "true")) ? true : false;
 var required = Msfg$getElementAttributeValueAsBoolean(dfe[aName], Array('msfg-required', 'required'), false);
 var displayName = (dfe[aName].displayname == null) ? aName : dfe[aName].displayname;
 switch (validationType)
 {
  case 'creditcard':
    return (creditCard(aName, required, displayName, showmessage));
    break;
 case 'phone':
    return (phone(aName, required, displayName, showmessage));
    break;
 default:
    return isFieldValidAndFocus(document.getElementsByName(aName)[0], initCap(validationType), !(required), displayName, showmessage);
 }
}

function checkTextBoxV6(aName)
{
 var elem = document.getElementsByName(aName)[0];
 var validationType = (elem.getAttribute("validationtype") == null) ? 'Alphanumeric' : elem.getAttribute("validationtype");
 var showmessage = (elem.getAttribute("showmessage") != null) ? (elem.getAttribute("showmessage").toLowerCase()) : "true";
 showmessage = ((showmessage == "true") || (showmessage == "yes")) ? true : false;
 var required = Msfg$getElementAttributeValueAsBoolean(elem, Array('msfg-required', 'required'), false);
 var displayName = (elem.getAttribute("displayname") == null) ? aName : elem.getAttribute("displayname");
 
 var isValid;
 
 switch (validationType)
 {
  case 'creditcard':
    isValid = (creditCard(aName, required, displayName, showmessage));
    break;
  case 'phone':
    isValid = (phone(aName, required, displayName, showmessage));
    break;
  default:
    isValid = isFieldValidAndFocus(document.getElementsByName(aName)[0], initCap(validationType), !(required), displayName, showmessage);
 }
 
    if (isValid)
    {
        switch (initCap(validationType))
        {
        case 'Integer':
        case 'YearOnly':
            var minimum = parseInt(Msfg$getElementAttributeValue(elem, Array('msfg-minimum'), '-2147483648'));
            var maximum = parseInt(Msfg$getElementAttributeValue(elem, Array('msfg-maximum'), '2147483647'));
            var numberNotInRangeMessage = Msfg$getElementAttributeValue(elem, Array('msfg-numbernotinrangemessage'), '');
            
            var integerValue = parseInt(elem.value);
            
            if (integerValue < minimum || integerValue > maximum)
            {
                if (typeof(numberNotInRangeMessage) == 'string' && numberNotInRangeMessage.length > 0)
                {                            
                    alert(numberNotInRangeMessage);
                }

                elem.focus();
                elem.select();
                
                isValid = false;
            }
            
            break;    
        }
    }
 
    if (isValid)
    {
        var onCustomValidate = elem.getAttribute('msfg-oncustomvalidate');

        if (onCustomValidate != null)
        {
            var id = elem.id;
            var value = elem.value;
            var sender = { controltovalidate:id };
            var message = elem.getAttribute('msfg-customvalidatemessage');
            var args = { Value:value, IsValid:true, Message:message };
            eval(onCustomValidate + '(sender, args);');               
            
            if (!args.IsValid)
            {
                if (typeof(args.Message) == 'string' && args.Message.length > 0)
                {                            
                    alert(args.Message);
                }

                elem.focus();
                elem.select();
            }
            
            isValid = args.IsValid;
        }
    }

    return isValid;
}

function checkRadioButtonsV5(aName)
{
 var dfe = frmForm.elements;
 var firstButton = dfe[aName][0];
 var validationMsg = (firstButton.valmsg == null) ? "" : firstButton.valmsg;
 var isChecked = false;
 for (f=0; f < dfe[aName].length; f++)
    isChecked = (dfe[aName][f].checked == true) ? true : isChecked;
 if (!isChecked)
 {
  if (validationMsg != "")
      alert(validationMsg);
  firstButton.focus();
  return false;
 }
 return true;
}
 
function checkRadioButtonsV6(aName)
{
    var elementName = aName;

    // Work arround a bug in IE where document.getElementsByName returns 
    // elements with id attributes that match elementName and not just elements with 
    // matching name attributes.  
    var elements = document.getElementsByName(elementName);
    var elementsWithName = new Array();
    var elementsWithNameCount = 0;
    
    for (var elementIndex = 0, elementCount = elements.length; elementIndex < elementCount; elementIndex++)
    {
        var element = elements[elementIndex];
    
        if (element.name == elementName)
        {
            elementsWithName[elementsWithNameCount++] = element;
        }
    }
    
    firstButtonID = elementsWithName[0].id;
    validationMsg = (elementsWithName[0].getAttribute("valmsg") == null) ? "" : elementsWithName[0].getAttribute("valmsg");
    isChecked = false;
    
    for (f=0; f< elementsWithName.length; f++)
    {
        isChecked = (elementsWithName[f].checked == true) ? true : isChecked;
    }
        
    if (!isChecked) 
    {
        if (validationMsg != "")
        {
            alert (validationMsg);
        }
        
        elementsWithName[0].focus();

        return false;
    } 
    
    return true;
}

function checkCheckBoxV5(aName)
{
 var dfe = frmForm.elements;
 var isGroup = (dfe[aName].group != null) ? true : false;
 var validationMsg = (dfe[aName].valmsg == null) ? "" : dfe[aName].valmsg;
 var oneIsChecked = false;
 if (isGroup)
 {
  var groupName = dfe[aName].group;
  for (var f=0; f<dfe.length; f++)
  {
   if (dfe[f].type != undefined && dfe[f].type.toLowerCase() == "checkbox")
   {
    if ((dfe[f].group != null) && (dfe[f].group == groupName))
       oneIsChecked = (dfe[f].checked) ? true : oneIsChecked;
   }
  }
 }
 else
 {
  oneIsChecked = dfe[aName].checked;
 }
 if (oneIsChecked)
   return true;
 else
 {
  if (validationMsg != "")
   alert (validationMsg);
  dfe[aName].focus();
  return false;
 }
}   
 
function checkCheckBoxV6(aName)
{
 var checkBox = document.getElementsByName(aName)[0];
 var isGroup = (checkBox.getAttribute("group") != null) ? true : false;
 var validationMsg = (checkBox.getAttribute("valmsg") == null) ? "" : checkBox.getAttribute("valmsg");
 var oneIsChecked = false;
 if (isGroup)
 {
  var groupName = checkBox.getAttribute("group");
  var dfe = frmForm.elements;
  for (var f=0; f<dfe.length; f++)
  {
   if (dfe[f].type != undefined && dfe[f].type.toLowerCase() == "checkbox")
   {
    if ((dfe[f].attributes.getNamedItem("group")) != null && (dfe[f].getAttribute("group") == groupName))
         oneIsChecked = (dfe[f].checked) ? true : oneIsChecked;
   }
  }
 }
 else
 {
  oneIsChecked = document.getElementsByName(aName)[0].checked;
 }
 if (oneIsChecked)
   return true;
  else
  {
   if (validationMsg != "")
    alert (validationMsg);
    checkBox.focus();
   return false;
  }
}

function checkSelectV6(aName)
{
 var selectBox = document.getElementsByName(aName)[0];
 var validationMsg = (selectBox.getAttribute("valmsg") == null) ? "" : selectBox.getAttribute("valmsg");
 var firstIsSelected = (selectBox[0].selected) ? true : false;
 if (firstIsSelected)
 {
  if (validationMsg != "")
   alert (validationMsg);
  selectBox.focus();
  return false;
 }
 else
  return true;
}

function checkSelectV5(aName)
{
 var dfe = frmForm.elements;
 var selectBox = dfe[aName];
 var validationMsg = (selectBox.valmsg == null) ? "" : selectBox.valmsg;
 var firstIsSelected = (selectBox[0].selected) ? true : false;
 if (firstIsSelected)
 {
  if (validationMsg != "")
   alert (validationMsg);
  selectBox.focus();
  return false;
 }
 else
    return true;
}

function checkSelectMultV5(aName)
{
 var dfe = frmForm.elements;
 var selectBox = dfe[aName];
 var validationMsg = (selectBox.valmsg == null) ? "" : selectBox.valmsg;
 var minimum = (selectBox.minimum == null) ? 1 : selectBox.minimum;
 var maximum = (selectBox.maximum == null) ? selectBox.options.length : selectBox.maximum;
 var numSelected = 0;
 for (var f=0; f < selectBox.options.length; f++)
   numSelected += (selectBox.options[f].selected) ? 1 : 0;
 
  if ((numSelected < minimum) || (numSelected > maximum))
  {
    if (validationMsg != "")
       alert (validationMsg);
     selectBox.focus();
     return false;
  }
  else
    return true;
}

function checkSelectMultV6(aName)
{
 var selectBox = document.getElementsByName(aName)[0];
 var validationMsg = (selectBox.getAttribute("valmsg") == null) ? "" : selectBox.getAttribute("valmsg");
 var minimum = (selectBox.getAttribute("minimum") == null) ? 1 : selectBox.getAttribute("minimum");
 var maximum = (selectBox.getAttribute("maximum") == null) ? selectBox.options.length : selectBox.getAttribute("maximum");
 var numSelected = 0;
 for (var f=0; f< selectBox.options.length; f++)
  numSelected += (selectBox.options[f].selected) ? 1 : 0;
 if ((numSelected < minimum) || (numSelected > maximum))
 {
   if (validationMsg != "")
      alert (validationMsg);
    selectBox.focus();
    return false;
 }
 else
   return true;
}


//-----------------------------------------------------------------------
// initCap Capitalises The First Letter of The Text and Uncapitalises the
// Rest. This Is Because Isfieldvalidandfocus Needs Its Validation Type
// Parameter This Way.
//-----------------------------------------------------------------------
function initCap(theText)
{
  var firstLetter = theText.substring(0,1).toUpperCase();
  var theRest = theText.substring(1, theText.length).toLowerCase();
  theText = firstLetter + theRest;
  
  switch (theText) 
  {
    case "Sortcode": 
        theText = "SortCode";
        break;
    case "Yearonly": 
        theText = "YearOnly";
        break;
  }
  
  return theText;
}

//Credit Card validation

function creditCard(aName, required, displayName, showMessage)
{
 var theNumber = frmForm.elements[aName].value;
 var theLength = theNumber.length;
 var justDigits = "";
 if ((theLength == 0) && (required))
 {
  if (showMessage)
    alert (displayName +  " cannot be left blank.");
    frmForm.elements[aName].focus();
    frmForm.elements[aName].select();
  return false;
 }
 if ((theLength == 0) && (!required))
    return true;
 if (theLength < 13)
 {
  if (showMessage)
    alert (displayName + " appears to be invalid.");
    frmForm.elements[aName].focus();
    frmForm.elements[aName].select();
  return false;
 }
 
 for (var f=0; f<theNumber.length; f++)
    justDigits += ((theNumber.charCodeAt(f) >= 48) && (theNumber.charCodeAt(f) <= 57)) ? theNumber.charAt(f) : "";
 expandedDigits = "";   
 for (f=0; f<justDigits.length; f++)
    expandedDigits += (f % 2 == 1) ? justDigits.charAt(f) : 2 * justDigits.charAt(f);
 total = 0;
 for (f=0; f<expandedDigits.length; f++)
    total +=  1 * expandedDigits.charAt(f); // 1 * to cast to integer otherwise it just appends!
 var isValid = (total % 10 == 0) ? true : false;
 if (isValid)
   return true;
 else
 {
  if (showMessage)
    alert(displayName +  " appears to be invalid.");
  frmForm.elements[aName].focus();
  frmForm.elements[aName].select();
  return false;
 }
}


function phone(aName, required, displayName, showMessage)
{
 var theNumber = frmForm.elements[aName].value;
 var theLength = theNumber.length;
 if ((theLength == 0) && (!required))
    return true;
 if (theLength < 10)
 {
  if (showMessage) alert (displayName + " must be a valid telephone number");
  frmForm.elements[aName].focus();
  frmForm.elements[aName].select();
  return false;
 }
 else
    return (isFieldValidAndFocus(document.getElementsByName(aName)[0], 'Numeric', !(required), displayName, showMessage));
}


function parseQueryString()
{
 var queryString = new Array();
 var theString = window.location.search.substring(1);
 var theParts = theString.split("&");
 for (i=0; i < theParts.length; i++)
 {
  var pos = theParts[i].indexOf('=');
  if (pos >= 0)
  {
   theKey = theParts[i].substring(0,pos);
   theValue = theParts[i].substring(pos+1);
   queryString[theKey] = theValue;
  }
 }
 return queryString;
}

function toggleValidation(anElement, yayOrNay) 
{
  var theDependentElements;
  var theToggledElements;

  if (anElement != '') {
	 var directArrays = (arguments[0].name == null) ? true : false;

	 // Get form name from either 1st array element or element passed in (if not an array)
	  if (directArrays) {
	   frmForm = document.getElementsByName(anElement[0])[0].form;
	  } else {
	   frmForm = anElement.form;
	  }

	  var isV6 = (frmForm.elements[0].attributes.getNamedItem != null) ? true : false;
	  var re = /\s*/g; //Regular expression that matches every space
	
	 if (directArrays)
	 {
	    theDependentElements = anElement;
	    yesOrNo =  (arguments.length == 2) ? yayOrNay : "yes";
	 }
	 else
	 {
	     if (isV6)
	     {
	      theDependentElements = (anElement.attributes.getNamedItem("dependentElements") == null) ? new Array() : anElement.attributes.getNamedItem("dependentElements").nodeValue.replace(re, "").split(",");
	      theToggledElements = (anElement.attributes.getNamedItem("toggledElements") == null) ? new Array() : anElement.attributes.getNamedItem("toggledElements").nodeValue.replace(re, "").split(",");  
	     }
	     else
	     {
	      theDependentElements = (anElement.dependentElements == null) ? new Array() : anElement.dependentElements.replace(re, "").split(",");
	      theToggledElements = (anElement.toggledElements == null) ? new Array() : anElement.toggledElements.replace(re, "").split(",");
	     }
	     var yesOrNo = (anElement.value.length > 0) ? "yes" : "no";
	 }
	
	 for (element in theDependentElements)
	 {
	  if (isV6)
	  {
	   elementToSwitch = document.getElementsByName(theDependentElements[element])[0];
	   if (elementToSwitch)
	   {
	   	attributeToSwitch = (elementToSwitch.type == "text") ? "required" : "validate";
		if (attributeToSwitch)
		{
		   	elementToSwitch.attributes.getNamedItem(attributeToSwitch).nodeValue = yesOrNo;
		   	elementToSwitch.attributes.getNamedItem('msfg-' + attributeToSwitch).nodeValue = yesOrNo;
		}
	   }
	  }
	  else
	  {
	   elementToSwitch = document.getElementsByName(theDependentElements[element])[0];
	   if (elementToSwitch)
	   {
		attributeToSwitch = (elementToSwitch.type == "text") ? "required" : "validate";
		if (attributeToSwitch)
		{
			elementToSwitch[attributeToSwitch] = yesOrNo;
			elementToSwitch['msfg-' + attributeToSwitch] = yesOrNo;
		}
	   }
	  }
	 }
	 
	 yesOrNo = (yesOrNo == "yes") ? "no" : "yes";

	 for (element in theToggledElements)
	 {
	  if (isV6)
	  {
	   elementToSwitch = document.getElementsByName(theToggledElements[element])[0];
	   attributeToSwitch = (elementToSwitch.type == "text") ? "required" : "validate";
	   elementToSwitch.attributes.getNamedItem(attributeToSwitch).nodeValue = yesOrNo;
	   elementToSwitch.attributes.getNamedItem('msfg-' + attributeToSwitch).nodeValue = yesOrNo;
	  }
	  else
	  {
	   elementToSwitch = document.getElementsByName(theToggledElements[element])[0];
	   attributeToSwitch = (elementToSwitch.type == "text") ? "required" : "validate";
	   elementToSwitch[attributeToSwitch] = yesOrNo;
	   elementToSwitch['msfg-' + attributeToSwitch] = yesOrNo;
	  }
	 }
  }
}

