/********************************************************************************
'CLASS:  verify.js
'DATE:   Aug 00
'DESC:   Verifies anwers.
'USAGE:  Note:  The InvalidMessage class is defined in a separate .js file.
'TODO:
'REVISION HISTORY:
'  Author   Date        Comment
'  DRM:     08/08/00    First draft
'  DRM:     12/07/00    Added support for 'select-multiple'
'  DRM:     04/13/01    Added Support for Ipsative Least/Most
'********************************************************************************/

//Variables
var verifyType;
var minChar;
var maxChar;
var required;
var invalidResponseId;
var failedCode = 0;
var attributeString = new String();
var message = new InvalidMessage(invalidAlert, SetInvalidFocus);
var invalidElement;
var processedElementNames = new String("*");
var validateIpsative = false;
var ipsativeLeastItems = [];
var ipsativeMostItems = [];
var ipsativeItemGroups = [];

//Functions
function VerifyDocument(){

   var i;
   var j;
   var k;
   var elemName;
   var attributeIndex;
   var valid = true;
   
   message.clear();
	processedElementNames = "*";
	
   for (i = 0; i < document.forms.length; i++){
      for (j = 0; j < document.forms[i].length; j++){
         if (ValidateFormElement(document.forms[i], document.forms[i].elements[j]) == false){
            if (valid != false){
               invalidElement = document.forms[i].elements[j];
            }
            valid = false;
         }
      }
   }
   
   if ((validateIpsative == true) && (valid == true)){
      valid = ValidateIpsative();
   }

   //if valid was set to something other than a boolean, error, let server verify
   if (valid != false){
      valid = true;
   }

   if (valid == false){
      if (message.displayMessage() == false){
         SetInvalidFocus();
      }
   }
   else {
      message.closePopup();
   }

   return valid;
}

//********************************************************************************
function ParseAttributeString(){

   if ((attributeString.length == 39) || (attributeString.length == 23)){
      required = parseInt(attributeString.substring(2, 3), 16);
      minChar = parseInt(attributeString.substring(5, 7), 16);
      maxChar = parseInt(attributeString.substring(7, 9), 16);
      verifyType = parseInt(attributeString.substring(11, 13), 16);
      invalidResponseId = parseInt(attributeString.substring(15, 23), 16);
      return true;
   }
   else
      return false;
}

//********************************************************************************
function VerifyElement(elemValue){

   var isValid = true;
   var i;

   if ((elemValue.length <= 0) && (required == 1)){
      isValid = false;
      failedCode = 1;
   }
   else{
      if (elemValue.length > 102399){
         //Request.form can't handle messages longer than 100kb - 1
         isValid = false;
         failedCode = 2;
      }
      else if (elemValue.length > 0){
         //no switch statement until JS1.2: NS4, IE4
         //if ((verifyType == 0)||(verifyType == 10)){
               //drop through to none
         //}
         if (verifyType == 11){ //VERIFY_INTEGER :
            var intValue = parseInt(elemValue);
            if (String(intValue) == elemValue){
               isValid = true;
            }
            else{
               for (i = 0; i < elemValue.length; i++) {
                  if (isNaN(elemValue.substring(i, i + 1))){
                     isValid = false;
                     break;
                  }
               }
            }
         }
         if (verifyType == 12){ //VERIFY_FLOAT :
            isValid = !isNaN(elemValue);
         }
         if (verifyType == 13){ //VERIFY_BIT :
            if ((elemValue == "1") || (elemValue == "0")){
               isValid = true;
            }
            else{
               isValid = false;
            }
         }
         if (verifyType == 14){ //VERIFY_EMAIL :
            if ((elemValue.indexOf("@") > 0) && (elemValue.indexOf(".") > 0) && (elemValue.lastIndexOf(".") > elemValue.indexOf("@"))){
               isValid = true;
            }
            else{
               isValid = false;
            }
         }
         if (verifyType == 15){ //VERIFY_SSN :
            if (RemoveNonDigits(elemValue).length == 9){
               isValid = true;
            }
            else{
               isValid = false;
            }
         }
         if (verifyType == 16){ //VERIFY_PHONE :
            var digitValue = RemoveNonDigits(elemValue);
            if ((digitValue.length >= 8) && (digitValue.length <= 20)){
               isValid = true;
            }
            else{
               isValid = false;
            }
         }
         if (verifyType == 17){ //VERIFY_DATE :
            isValid = !isNaN(Date.parse(elemValue));
         }
         if (verifyType == 18){ //VERIFY_CURRENCY :
            isValid = !isNaN(parseFloat(RemoveNonDigits(elemValue)))
         }
         if ((verifyType == 19)||(verifyType == 20)){ //VERIFY_STRING :
            if (minChar > 0){
               if (elemValue.length < minChar){
                  isValid = false;
               }
               else{
                  if (maxChar > 0){
                     if (elemValue.length > maxChar){
                        isValid = false;
                     }
                  }
                  else{
                     failedCode = 1;
                  }
               }
            }
            else{
               if (maxChar > 0){
                  if (elemValue.length > maxChar){
                     isValid = false;
                  }
               }
               else{
                  failedCode = 1;
               }
            }               
         }
         if (isValid == false){
            failedCode = verifyType;
         }
      }
   }
   
   return isValid;
}

//********************************************************************************
function RemoveNonDigits(stringValue){

   var returnValue = new String();

   for (var i = 0; i < stringValue.length; i++){
      
      // no switch until js1.2
      if ((stringValue.charAt(i) == "0")||
         (stringValue.charAt(i) == "1")||
         (stringValue.charAt(i) == "2")||
         (stringValue.charAt(i) == "3")||
         (stringValue.charAt(i) == "4")||
         (stringValue.charAt(i) == "5")||
         (stringValue.charAt(i) == "6")||
         (stringValue.charAt(i) == "7")||
         (stringValue.charAt(i) == "8")||
         (stringValue.charAt(i) == "9")){
            returnValue += stringValue.charAt(i);
      }
   }

   return returnValue;
}

//********************************************************************************
function VerifyRadio(currentForm, radioElement){

   var checked = false;
   var i;
   
   if (processedElementNames.indexOf("*" + radioElement.name + "*") < 0){ 
      if (required == 1){
         for (i = 0; i < currentForm.length; i++){
            if (!checked){
               if ((currentForm.elements[i].name == radioElement.name) && (currentForm.elements[i].type == "radio")){
                  if (currentForm.elements[i].checked){
                     if (currentForm.elements[i].value != invalidResponseId){
                        checked = true;
                     }
                  }
               }
            }
         }
      }
      else{
         checked = true;
      }
   
      if (!checked) {
         required == 1 ? failedCode = 1 : failedCode = verifyType;
      }

      processedElementNames += radioElement.name + "*";
      return checked;
   }
   else {
      return true;
   }
}

//********************************************************************************
function VerifyMultiselectDate(currentForm, msdElement){

   var isValid = true;
   var i, d;
   var day, month, year;
   var e;
   var elemValue;
   
   day=month=year=0;

   if (processedElementNames.indexOf("*" + msdElement.name + "*") < 0){
      for (i = 0; i < currentForm.length; i++){
         e = currentForm.elements[i];
   		if ((e.name == msdElement.name) && 
   			 (String(e.type).indexOf("select") >= 0)){
   			 elemValue = e.options[e.selectedIndex].value
   		    if (elemValue < 200) {
   		       month = elemValue - 100;
   		    }
   		    else if ((elemValue > 200) 
   		         && (elemValue < 300)) {
	   	       day = elemValue - 200;
	   	    }
	   	    else if (elemValue > 10000) {
	   	       year = elemValue - 10000;
	   	    }
	   	}   
      }
   
      if (day+month+year == 0){
	   	if (required == 1){
	   		isValid = false;			//blank and required
   			failedCode = 1;
   		}
      }
      else {
   		if (day == 0) day = 1;
   		//JavaScript considers 02/31/2001 to be a valid date (i.e. 03/03/2001) but we do not!
   		if (!isNaN(Date.parse(month + "/" + day + "/" + year))) {
   		   month -= 1;						//zero-based months
   			d = new Date(year, month, day);
   			if (!(d.getYear() == year || d.getYear() + 1900 == year) 
   			      || d.getMonth() != month || d.getDate() != day){
   				isValid = false;
   				failedCode = verifyType;
   			}
   		}
   		else {
   			isValid = false;
   			failedCode = verifyType;
   		}
      }

   	processedElementNames += msdElement.name + "*";
   }
   
   return isValid;
}

//********************************************************************************
function SetInvalidFocus(){

   if (invalidElement != null){
      if (String(invalidElement.type).indexOf("select") == -1){ 
         if (String(invalidElement.type).indexOf("radio") == -1){ 
            invalidElement.select();
         }
            invalidElement.focus();
      }
      else{
         if ((invalidElement.selectedIndex) && (invalidElement.selectedIndex >= 0)){
            invalidElement.options[invalidElement.selectedIndex].selected = true;
         }
      }
   }

}

//********************************************************************************
function ValidateServedPage(){
   //check a page received from the server for invalid items
   var i;
   var j;
   var k;
   var validationType;
   var itemId;
   var itemGroupId;
   var valid;
   
   for (k = 0; k < document.images.length; k++){
      validationType = message.getValidationType(document.images[k].name);
      if ((validationType == 2) || (validationType == 4)){
         //find item & itemgroup ids
         itemId = message.getItemId(document.images[k].name);
         itemGroupId = message.getItemGroupId(document.images[k].name);
         for (i = 0; i < document.forms.length; i++){
            for (j = 0; j < document.forms[i].length; j++){
               if (document.forms[i].elements[j].name.indexOf(itemGroupId + "::" + itemId) > 0){
                  valid = ValidateFormElement(document.forms[i], document.forms[i].elements[j]);
                  if (valid == true){
                     //we don't know why it was rejected; give misc. message
                     message.addInvalidItem(document.forms[i].elements[j], 3, required, false);
                  }
                  break;
               }
            }
         }
      }
   }
   message.displayMessage();
   
}

//********************************************************************************
function ValidateFormElement(elemForm, elem){
   var i;
   var elemName;
   var attributeIndex;
   var valid = true;

   elemName = new String(elem.name);
	attributeIndex = elemName.indexOf("::A::");
	
	if ((attributeIndex > 0 ) && (elem.type != "image")){
	   attributeString = elemName.substring(attributeIndex + 5);
	   ParseAttributeString();
	   if (String(elem.type).indexOf("select") == -1){
	      if (String(elem.type).indexOf("radio") == -1){
	         if (VerifyElement(elem.value) == false){
	            valid = false;
	            message.addInvalidItem(elem, failedCode, required);
	         }
	      }
	      else{
	         if (VerifyRadio(elemForm, elem) == false){
	            valid = false;
	            message.addInvalidItem(elem, failedCode, required);
	        }
	      }
	   }
	   else{
	      if (String(elem.type).indexOf("multiple") == -1){
	         if (required == 1) {
   	         if (elem.options[elem.selectedIndex].value == invalidResponseId){
   	            valid = false;
   	            message.addInvalidItem(elem, 1, required);
   	         }
   	         else if (elem.options[elem.selectedIndex].text == ""){
   	            valid = false;
   	            message.addInvalidItem(elem, 1, required);
   	         }
   	         else if (verifyType == 17){
   	            if (VerifyMultiselectDate(elemForm, elem) == false){
   	               valid = false;
	                  message.addInvalidItem(elem, failedCode, required);
   	            }
   	         }
	            else {
   	            if (VerifyElement(elem.options[elem.selectedIndex].value) == false){
   	               valid = false;
   	               message.addInvalidItem(elem, failedCode, required);
   	            }
   	         }
   	      }
	      }
	      else{
	         if (required == 1){
	            if (elem.options.length < 1){
	               valid = false;
	               message.addInvalidItem(elem, 1, required);
	            }
	            else if (elem.selectedIndex < 0){
	               valid = false;
	               message.addInvalidItem(elem, 1, required);
	            }
	            else if (elem.options[elem.selectedIndex].value == invalidResponseId){
	               valid = false;
	               message.addInvalidItem(elem, 1, required);
	            }
	         }
	         for (i = 0; i < elem.options.length; i++){
	            if (VerifyElement(elem.options[i].value) == false){
	               valid = false;
	               message.addInvalidItem(elem, failedCode, required);
	            }
	         }
	      }
	   }
	}
	
	return valid;
}

//********************************************************************************
function SetIpsativeItems(itemGroups, leastItems, mostItems){
   var groupArray;
   var leastArray;
   var mostArray;

   if ((itemGroups != null) && (leastItems != null) 
         && (mostItems != null)) {
      if (leastItems.split){
         //split in 1.1 and up
         groupArray = itemGroups.split("|");
         leastArray = leastItems.split("|");
         mostArray = mostItems.split("|");
      }
      else{
         groupArray = splitToArray(itemGroups, "|");
         leastArray = splitToArray(leastItems, "|");
         mostArray = splitToArray(mostItems, "|");
      }
      if ((leastArray.length == mostArray.length) 
            && (leastArray.length != 0)){
         validateIpsative = true;
         ipsativeItemGroups = groupArray;
         ipsativeLeastItems = leastArray;
         ipsativeMostItems = mostArray;
      }
   }

}

//********************************************************************************
// function ValidateIpsative()
// Assumes: Ipsative items may only be radio.
//  
function ValidateIpsative(){
   var ipsValid = true;
   var i;
   var j;
   var k;
   var l;
   var elem;
   var leastElem;
   var mostElem;
   var itemGroupId;
   var leastItem;
   var mostItem;
   
   for (l = 0; l < ipsativeItemGroups.length; l++){
      itemGroupId = ipsativeItemGroups[l]
      leastItem = 0;
      mostItem = 0;
      leastElem = null;
      mostElem = null;
      for (i = 0; i < document.forms.length; i++){
         for (j = 0; j < document.forms[i].length; j++){
            elem = document.forms[i].elements[j];
            if (elem.type == "radio"){
               for (k = 0; k < ipsativeLeastItems.length; k++){
                  if ((elem.name.indexOf
                        (itemGroupId + "::" + ipsativeLeastItems[k]) >= 0)
                        && leastElem == null){
                     leastElem = elem;
                  }
                  if ((elem.name.indexOf
                        (itemGroupId + "::" + ipsativeMostItems[k]) >= 0)
                        && mostElem == null){
                     mostElem = elem;
                  }
                  if ((elem.name.indexOf
                        (itemGroupId + "::" + ipsativeLeastItems[k]) >= 0)
                        && elem.checked){
                     leastItem = elem.value;
                     leastElem = elem;
                  }
                  if ((elem.name.indexOf
                        (itemGroupId + "::" + ipsativeMostItems[k]) >= 0)
                        && elem.checked){
                     mostItem = elem.value;
                     mostElem = elem;
                  }
               }
            }
         }
      }
      if (leastItem == mostItem){
         ipsValid = false;
         message.addInvalidItem(mostElem, 4, 0, false);
         message.addInvalidItem(leastElem, 4, 0, false);
      }
      else {
         if (leastItem == 0){
            ipsValid = false;
            message.addInvalidItem(leastElem, 4, 0, false);
         }
         if (mostItem == 0){
            ipsValid = false;
            message.addInvalidItem(mostElem, 4, 0, false);
         }
      }
   }

   return ipsValid;

}

//********************************************************************************
function splitToArray(itemList, delim) {
   //init itemArray to an array; no Array object til 1.1
   var itemArray = [];
   var counter = 0;
   var priorIndex = 0;
   var nextIndex = 0;
   
   while (priorIndex >= 0) {
      nextIndex = itemList.indexOf(delim);
      if (nextIndex >= 0) {
         itemArray[counter] = itemList.substring(priorIndex, nextIndex);
         counter++;
      }
      else {
         itemArray[counter] = itemList.substring(priorIndex);
      }
      priorIndex = nextIndex;
   }
   
   return itemArray;
}


