/*

Form Validation Example
=======================

In form page:
<script language="Javascript">
function validateLoginForm(){
  
  // Create a new JSForm object
  var myForm = new JSForm();
   
  myForm.addElement(new JSFormElement(document.frmLogin.userName,TEXTBOX,true, "Please enter a user name", TEXT));
  
  return myForm.validate();
}
</script>

<form name="frmValidateLogin" onsubmit="return validateLoginForm()">
  <input type="text" name="userName">
  <input type="submit" value="Submit">
</form>

*/

// Data types
var TEXT=0, EMAIL_ADDRESS=1, NUMBER=2, POS_INT=3, NEG_INT=4, NZ_POS_INT=5, NZ_NEG_INT=6, POSTAL_CODE=7, ZIP_CODE=8, JPG=9, IMAGE=10;

// Element types
var TEXTBOX="textbox", CHECKBOX="checkbox", RADIO="radio";

/*
* Returns true if the value is a valid email address. Otherwise, it returns false.
*/
function isEmailAddress(value) {
  var regex = /^[\w\.-]+@[\w\.-]+\.[a-zA-Z]{2,3}$/;
    if (!regex.test(value)) {
      return false;
    } else {
      return true;
    }
}

function isPostalCode(value){
  var regex = /^[a-zA-Z]\d[a-zA-Z][\s]*\d[a-zA-Z]\d$/;
  if (!regex.test(value)) {
    return false;
  } else {
    return true;
  }
}

function isZipCode(value){
  var regex = /^[\d]{5}$/;
    if (!regex.test(value)) {
      return false;
    } else {
      return true;
  }
} 
  
/*
* Returns true if the value is undefined, null, or an empty string. Otherwise,
* it returns false.
*/
function isEmpty(value) {
  return ((value == undefined) || (value == null) || (value == ""));
}

/*
* Returns true if the value is a valid number (including decimals). Otherwise,
* it returns false.
*/
function isNumber(value) {
  var regex = /^[\d]*[\.]{0,1}[\d]*$/;
  if(!regex.test(value)) {
    return false;
  } else {
    return true;
  }
}

/* true if str ends with end.  if ignoreCase is true, the functions ignores case */
function endsWith(str,end,ignoreCase) {
	if (str.length-end.length<0) return false;
	var ending = str.substring(str.length-end.length,str.length);

	if (ignoreCase) {
		return (ending.toUpperCase() == end.toUpperCase());
	} else {
		return (ending == end);
	}
}

function isInteger(value) {
  var regex = /^[\d]*$/;
  if(!regex.test(value)) {
    return false;
  } else {
    return true;
  }
}

/*
* Trims leading and trailing whitespace.
*/
String.prototype.trim = function() {
  var x=this;
  x=x.replace(/^\s*(.*)/, "$1");
  x=x.replace(/(.*?)\s*$/, "$1");
  return x;
}

/*
* The JSForm class represents a document form's properties and methods.
*/
function JSForm() {

  this.elementList = new Array();

  if(typeof(_jsform_prototype_called) == 'undefined') {
    _jsform_prototype_called = true;
    JSForm.prototype.validate = validate;
    JSForm.prototype.addElement = addElement;
  }

  /*
  * Adds an element to the form.
  */
  function addElement(element) {
    this.elementList.push(element);
  }

  /*
  * Validates all the elements in the form and returns true if successful.
  * Otherwise, it returns false.
  */
  function validate() {
    for (i=0; i < this.elementList.length; i++) {
      element = this.elementList[i];
      if(!element.validate())
        return false;
    }
    
    return true;
  }
}

/*
* The JSFormElement class represents an element in a document form. It requires the
* following parameters:
*   - elementObject : object : a reference to the document form element object
*   - elementType : string : whether it is a TEXTBOX, CHECKBOX, or RADIO
*   - required : boolean : whether it is required or not
*   - errorMessage : string : error message to be displayed
*   - dataType : string : whether it is TEXT, EMAIL_ADDRESS, or NUMBER
*/
function JSFormElement(elementObject, elementType, required, errorMessage, dataType) {

  this.elementObject = elementObject;
  this.elementType = elementType;
  this.required = required;
  this.errorMessage = errorMessage;
  this.dataType = dataType;

  if (typeof(_formelement_prototype_called) == 'undefined') {
    _jsformelement_prototype_called = true;
    JSFormElement.prototype.validate = validate;
    JSFormElement.prototype.displayError = displayError;
  }

  /*
  * Validates the element and returns true if successful. Otherwise, it returns
  * false.
  */
  function validate() {
    if(this.required) {
      if(this.elementType == RADIO) {
        checked = false;

        for(j=0; j < this.elementObject.length; j++) {
          if(this.elementObject[j].checked == true) {
            checked = true;
          }
        }
        if(!checked) {          
          displayError(this.errorMessage, this.elementObject);
          return false;
        }
      } else if(this.elementType == CHECKBOX) {
        if(!this.elementObject.checked) {
          displayError(this.errorMessage, this.elementObject);
          return false;
        }
      } else {


        switch(this.dataType) {  
          
          case TEXT:
            if(isEmpty(this.elementObject.value)) {
              displayError(this.errorMessage, this.elementObject);              
              return false;
            }
            break;
          case EMAIL_ADDRESS:
            if(isEmpty(this.elementObject.value) || !isEmailAddress(this.elementObject.value)) {
              displayError(this.errorMessage, this.elementObject);
              return false;
            }
            break;
          case NUMBER:
            if(isEmpty(this.elementObject.value) || !isNumber(this.elementObject.value)) {
              displayError(this.errorMessage, this.elementObject);
              return false;
            }
            break;
          case POS_INT:
            if(isEmpty(this.elementObject.value) || !isInteger(this.elementObject.value) || this.elementObject.value < 0) {
              displayError(this.errorMessage, this.elementObject);
              return false;
            }
            break;
          case NZ_POS_INT:
            if(isEmpty(this.elementObject.value) || !isInteger(this.elementObject.value) || this.elementObject.value < 1) {
              displayError(this.errorMessage, this.elementObject);
              return false;
            }
            break;
          case NEG_INT:
            if(isEmpty(this.elementObject.value) || !isInteger(this.elementObject.value) || this.elementObject.value > 0) {
              displayError(this.errorMessage, this.elementObject);
              return false;
            }
            break;
          case NZ_NEG_INT:
            if(isEmpty(this.elementObject.value) || !isInteger(this.elementObject.value) || this.elementObject.value > 1) {
              displayError(this.errorMessage, this.elementObject);
              return false;
            }
            break;
          case POSTAL_CODE:
            if(isEmpty(this.elementObject.value) || !isPostalCode(this.elementObject.value)) {
              displayError(this.errorMessage, this.elementObject);
              return false;
            }
            break;                        
          case ZIP_CODE:
            if(isEmpty(this.elementObject.value) || !isZipCode(this.elementObject.value)) {
              displayError(this.errorMessage, this.elementObject);
              return false;
            }
            break;
           case JPG:
             if (!endsWith(this.elementObject.value,"JPG",true)) {
             
             	displayError(this.errorMessage, this.elementObject);
             	return false;
             }
             break;      
           case IMAGE:
             if (!endsWith(this.elementObject.value,"GIF",true) &&
                 !endsWith(this.elementObject.value,"JPG",true) && 
                 !endsWith(this.elementObject.value,"PNG",true) && 
                 !endsWith(this.elementObject.value,"BMP",true) &&
                 !endsWith(this.elementObject.value,"JPEG",true)) {
             
             	displayError(this.errorMessage, this.elementObject);
             	return false;
             }
             break; 
          default:
        }
      }
    } else {

    }

    return true;
  }

  /*
  * Displays an alert box with an error message and draws focus to the element.
  */
  function displayError(errorMessage, element) {
    alert(errorMessage);
    
    if(!(element.value == undefined))
      element.focus();
  }
  
  
  
  
}