

function validateCompleteForm (objForm) {
return _validateInternal(objForm, 0);
}

function validateStandard (objForm) {
return _validateInternal(objForm, 1);
}

function validate_one(element) {
if (!element.form.getLabelsDone) getLabels(element.form);

field = new Field(element);

if (field.value=='') field.SetStatus('');
else if (!field.IsValid()) field.SetStatus('error');
else { field.ResetClass(); }


}


function _validateInternal(form, nErrorThrowType){
var strErrorMessage = ""; var objFirstError = null;
if (!form.getLabelsDone) getLabels(form);
if (nErrorThrowType == 0) {
strErrorMessage = (form.err) ? form.err : _getLanguageText("err_form");
}

var fields = _GenerateFormFields(form);
for (var i = 0; i < fields.length; ++i){
var field = fields[i];
field.ResetClass();
if (!field.IsValid()){
field.SetStatus('error');
if (nErrorThrowType == 1) {
_throwError(field);
return false;
}else{
if (objFirstError == null) objFirstError = field;
strErrorMessage = _handleError (field, strErrorMessage);
bError = true;
}
}
}
if (objFirstError != null) {
alert(strErrorMessage);
objFirstError.element.focus();
return false;
}
return true;
}

function _getLanguageText(id){
objTextsInternal = new _jsVal_Language();
objTexts = null;
try {
objTexts = new jsVal_Language();
} catch (ignored){};
switch (id) {
case "err_form": strResult = (!objTexts || !objTexts.err_form) ? objTextsInternal.err_form : objTexts.err_form; break;
case "err_enter": strResult = (!objTexts || !objTexts.err_enter) ? objTextsInternal.err_enter : objTexts.err_enter; break;
case "err_select": strResult = (!objTexts || !objTexts.err_select) ? objTextsInternal.err_select : objTexts.err_select; break;
}
return strResult;
}

function _GenerateFormFields(form){
var arr = new Array();
for (var i = 0; i < form.length; ++i){
var element = form.elements[i];
var index = _getElementIndex(arr,element);
if (index) {
if (index == -1) arr[arr.length] = new Field(element);
else arr[index].Merge(element);
}
}
return arr;
}

function _getElementIndex(arr, element){
if (!element.name) return;
var elementName = element.name.toLowerCase();
for (var i = 0; i < arr.length; ++i){
if (arr[i].element.name.toLowerCase() == elementName) return i;
}
return -1;
}


function _jsVal_Language() {
this.err_form = "אנא מלא/תקן את שדות הבאים:\n\n";
this.err_select = "Please select a valid \"%FIELDNAME%\"";
this.err_enter = "נא להזין שדה: %FIELDNAME%";
}


function Field(element){
this.name = element.name;
this.type = element.type;
this.form = element.form;
this.label = element.label;
this.element = element;
this.exclude = element.exclude || element.getAttribute('exclude');
this.err = element.err || element.getAttribute('err');
this.required = _parseBoolean(element.required || element.getAttribute('required'));
this.realname = element.realname || element.getAttribute('realname');
if (document.getElementById) this.statusImg=document.getElementById(this.name+'_status');

switch (this.type){
case "textarea":
case "password":
case "text":
this.value = element.value;
this.equalto = element.equalto || element.getAttribute('equalto');
this.minLength = element.minlength || element.getAttribute('minlength');
this.maxLength = element.maxlength || element.getAttribute('maxlength');
this.regexp = this._getRegEx(element);
this.minValue = element.minvalue || element.getAttribute('minvalue');
this.maxValue = element.maxvalue || element.getAttribute('maxvalue');
break;
case "select-one":
case "select-multiple":
this.values = new Array();
for (var i = 0; i < element.options.length; ++i){
if (element.options[i].selected && (!this.exclude || element.options[i].value != this.exclude)){
this.values[this.values.length] = element.options[i].value;
}
}
this.min = element.min || element.getAttribute('min');
this.max = element.max || element.getAttribute('max');
break;
case "checkbox":
this.min = element.min || element.getAttribute('min');
this.max = element.max || element.getAttribute('max');
case "radio":
this.required = _parseBoolean(this.required || element.getAttribute('required'));
this.values = new Array();
if (element.checked){
this.values[0] = element.value;
}
this.elements = new Array();
this.elements[0] = element;
break;
}
}

Field.prototype.Merge = function(element){
var required = _parseBoolean(element.getAttribute('required'));
if (required) this.required = true;
if (!this.err) this.err = element.getAttribute('err');
if (!this.equalto) this.equalto = element.getAttribute('equalto');
if (!this.realname) this.realname = element.getAttribute('realname');
if (!this.max) this.max = element.getAttribute('max');
if (!this.min) this.min = element.getAttribute('min');
if (!this.regexp) this.regexp = this._getRegEx(element);
if (element.checked) this.values[this.values.length] = element.value;

this.elements[this.elements.length] = element;
}

Field.prototype.IsValid = function(){
switch (this.type){
case "textarea":
case "password":
case "text":
return this._ValidateText();
case "select-one":
case "select-multiple":
case "radio":
case "checkbox":
return this._ValidateGroup();
default:
return true;
}
}

Field.prototype.SetStatus = function(Status) {
if (Status=='error') {
if (this.elements) for (var i=0; i<this.elements.length; ++i) this.removeClassName(this.elements[i], 'error');
else this.addClassName(this.element, 'error');
if (this.label) this.addClassName(this.label, 'error');
}else {
this.ResetClass();
}
}


Field.prototype.hasClassName = function(element, className) {
var elementClassName = element.className;
return (elementClassName.length > 0 && (elementClassName == className || new RegExp("(^|\\s)" + className + "(\\s|$)").test(elementClassName)));
}
Field.prototype.addClassName = function(element, className) {
if (!this.hasClassName(element, className)) element.className += (element.className ? ' ' : '') + className;
}
Field.prototype.removeClassName = function(element, className) {
element.className = element.className.replace(new RegExp("(^|\\s+)" + className + "(\\s+|$)"), ' ').replace(/^\s+/, '').replace(/\s+$/, '');
}


Field.prototype.ResetClass = function(){
if (this.elements) for (var i=0; i<this.elements.length; ++i) this.removeClassName(this.elements[i], 'error');
else this.removeClassName(this.element, 'error');
if (this.label) this.removeClassName(this.label, 'error');
}

Field.prototype._getRegEx = function(element){
regex = element.regexp || element.getAttribute('regexp')
if (regex == null) return null;
retype = typeof(regex);
if (retype.toUpperCase() == "FUNCTION")
return regex;
else if ( (retype.toUpperCase() == "STRING") && !(regex=="email") && !(regex=="date") && !(regex=="tel")
&& !(regex=="pc") && !(regex=="zip") && !(regex=="money") 
&& !(regex=="creditcard") && !(regex=="postalzip"))
{
nBegin = 0; nEnd = regex.length;
if (regex.charAt(0) == "/") nBegin=1;
if (regex.charAt(regex.length-1) == "/") nEnd=regex.length-1;
return new RegExp(regex.slice(nBegin, nEnd));
}
else {
return regex;
}
}

Field.prototype._ValidateText = function(){
if (this.equalto && this.form[this.equalto]){
if (this.value != this.form[this.equalto].value) return false;
}
if (this.required && !trim(this.value)){
return false;
}
if (this.value && (this.minLength && trim(this.value).length < this.minLength)){
return false;
}
if (this.value && (this.maxLength && trim(this.value).length > this.maxLength)){
return false;
}
if (this.regexp && !_checkRegExp(this.regexp, this.value)){
if (!this.required && this.value) return false;
if (this.required) return false;
}
if (this.required){
var fValue = parseFloat(this.value);
if ((this.minValue || this.maxValue) && isNaN(fValue)) return false;
if (this.minValue && fValue < this.minValue) return false;
if (this.maxValue && fValue > this.maxValue) return false
}
return true;
}

Field.prototype._ValidateGroup = function(){
if (this.required && (this.values=='' || this.values.length==0)) return false;
if (this.required && this.min && this.min > this.values.length) return false;
if (this.required && this.max && this.max < this.values.length) return false;
return true;
}



function trim(str) {
return str.replace(/^\s*|\s*$/g,"");
}

function _handleError (field, strErrorMessage) {
var obj = field.element;
strNewMessage = strErrorMessage + ( (field.realname)? field.realname : ((obj.id) ? obj.id : obj.name) ) + "\n";
return strNewMessage;
}

function _throwError(field){
var obj = field.element;
switch (field.type){
case "text":
case "password":
case "textarea":
alert(_getError(field, "err_enter"));
obj.focus();
break;
case "select-one":
case "select-multiple":
case "radio":
case "checkbox":
alert(_getError(field, "err_select"));
break;
}
}

function _getError(field, str){
var obj = field.element;
strErrorTemp = (field.err) ? field.err : _getLanguageText(str);
return strErrorTemp.replace("%FIELDNAME%", (field.realname)? field.realname : ((obj.id) ? obj.id : obj.name));
}

function _parseBoolean(value){
return !(!value || value == 0 || value == "0" || value == "false");
}

function _checkRegExp(regx, value){
switch (regx){
case "email": return ((/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,5})+$/).test(value));
case "date": return dateCheck(value);
case "tel": return ((/^1?[\- ]?\(?\d{3}\)?[\- ]?\d{3}[\- ]?\d{4}$/).test(value));
case "pc": return ((/^[a-z]\d[a-z] ?\d[a-z]\d$/i).test(value));
case "zip": return ((/^\d{5}$/).test(value));
case "money": return ((/^\d+([\.]\d\d)?$/).test(value));
case "creditcard": return (!isNaN(value));
case "postalzip":
if(value.length==6 || value.length==7) return((/^[a-zA-Z]\d[a-zA-Z] ?\d[a-zA-Z]\d$/).test(value));
if(value.length==5 || value.length==10) return((/^\d{5}(\-\d{4})?$/).test(value));
break;
default:
return (regx.test(value));
}
}

function dateCheck(str){
year=month=day=hour=minute=false;
var re = new RegExp("^([0-9]{1,2})[./]([0-9]{1,2})[./]([0-9]{2,4})( ([0-9]{1,2}):([0-9]{1,2}))?$");
if ( (ar=re.exec(str))!=null ) {
if (ar[3].length==2) ar[3]='20'+ar[3];
year=ar[3]; month=ar[2]; day=ar[1]; hour=ar[5]; minute=ar[6];
}else {
var re = new RegExp("^([0-9]{4})-([0-9]{1,2})-([0-9]{1,2})( ([0-9]{1,2}):([0-9]{1,2}))?$");
if ((ar=re.exec(str))!=null) {
year=ar[1]; month=ar[2]; day=ar[3]; hour=ar[5]; minute=ar[6];
}
}

if (!year || !month || !day) return false;
if ( hour && (hour>23 || minute>59) ) return false;

var date1 = new Date(year, Number(month-1), day);
if ( Number(month-1) != date1.getMonth() ) return false;
return true;
}

function getLabels(form) {
if (form.getLabelsDone) return;
if(!document.getElementsByTagName) return;
var labelList = form.getElementsByTagName('label');
for(var lbl=0; lbl<labelList.length; lbl++) { // loop through label array attempting to match each 'for' attribute to the id of the current element
if(labelList[lbl]['htmlFor']) label=labelList[lbl]['htmlFor']
else if(labelList[lbl].getAttribute('for')) label = labelList[lbl].getAttribute('for');
else label=false; // label not found

if (label && form[label]) form[label].label=labelList[lbl];
}
form.getLabelsDone=true;
}
