var cdeObj = null;
var blue = 0;
inc = 8;
delay = 30;

function Form_Validator(pForm, pErrorMessageContainer) {
	this._form = document.forms[pForm];
	if(!this._form) {
		throw new Error("Error: could not get form named " + pForm);
		return;
	}
	this._aryValidationElement = new Array();
	cdeObj = this;
	this._errorMessageContainer = document.getElementById(pErrorMessageContainer);
	this._hasErrors = false;
	_this = this;
	this._form.onsubmit = function() {return Form_Validator.prototype.submitForm(_this)};
}

Form_Validator.prototype.addValidation = function(pElementName, pValidationMethod, pErrorMessage) {
	if (!this._form.elements[pElementName]) {
		throw new Error("Error: could not get form element named " + pElementName);
		return;
	}
	this._form.elements[pElementName]._form = this._form;
	this._form.elements[pElementName]._validationMethod = pValidationMethod;
	this._form.elements[pElementName]._errorMessage = pErrorMessage;
	this._form.elements[pElementName]._errorMessageContainer = this._errorMessageContainer;
	this._aryValidationElement.push(this._form.elements[pElementName]);
}

Form_Validator.prototype.submitForm = function(pThis) {
	// loop through all elements and check for validation
	var _isValid = true;
	pThis._hasErrors = false;
	var _errorMessageContainer = pThis._errorMessageContainer;
	if (_errorMessageContainer) {
		_errorMessageContainer.innerHTML = "";
		_errorMessageContainer.style.display = "none";
	}
	Form_Validator.prototype.doVals(pThis);
	if (pThis._hasErrors) {
		return false;
	}
	return true;
}

Form_Validator.prototype.doVals = function(pThis) {
	for (var i=0; i<pThis._aryValidationElement.length; i++) {
		Form_Validator.prototype.validateElement(pThis, pThis._aryValidationElement[i], "buildMsg");
	}
	for (var i=0; i<pThis._aryValidationElement.length; i++) {
		Form_Validator.prototype.validateElement(pThis, pThis._aryValidationElement[i], "buildIconFlag");
	}
}

Form_Validator.prototype.buildFlag = function(pThis, pElement, pFieldError) {
	if (document.getElementById(pElement.name + "Icon")) {
		// reset
		document.body.removeChild(document.getElementById(pElement.name + "Icon"));
		pElement.onblur = "";
	}
	if (pFieldError) {
		var oDiv = document.body.appendChild(document.createElement("div"));
		oDiv.id = pElement.name + "Icon";
		oDiv.className = "pIcon";
		oDiv.style.position = "absolute";
		var mOffY = 0;
		var mOffX = 0;
		setLyr(pElement, oDiv, parseInt(pElement.offsetWidth) + mOffX, mOffY);
		pElement._this = this;
		if (pElement.nodeName == "INPUT") {
			pElement.onblur = function() {
				//alert(pThis);
				pThis._hasErrors = false;
				this._errorMessageContainer.innerHTML = "";
				Form_Validator.prototype.doVals(pThis);
				if (pElement.value != "") {
					blue = 0;
					Form_Validator.prototype.fadeToWhite();
				}
			}
		} else if (pElement.nodeName == "SELECT") {
			pElement.onchange = function() {
				pThis._hasErrors = false;
				this._errorMessageContainer.innerHTML = "";
				Form_Validator.prototype.doVals(pThis);
				//if (pElement.selectedIndex != 0) {
					blue = 0;
					Form_Validator.prototype.fadeToWhite();
				//}
			}
		}
	}
}

Form_Validator.prototype.buildErrorMessage = function(pElement, pErrorMessage) {
	var _errorMessageContainer = pElement._errorMessageContainer;
	_errorMessageContainer.style.display = "block";
	//_errorMessageContainer.innerHTML += pElement._errorMessage + "<br />";
	_errorMessageContainer.innerHTML += pErrorMessage + "<br />";
}

Form_Validator.prototype.validateElement = function(pThis, pElement, pBuildType) {
	var command = pElement._validationMethod;
	var cmdvalue = "";
	var _eq = pElement._validationMethod.indexOf('=');
	if (_eq >= 0) {
		command  = pElement._validationMethod.substring(0, _eq);
		cmdvalue = pElement._validationMethod.substr(_eq + 1);
	} else {
		command = pElement._validationMethod;
	}
	switch (command) {
		case "req":
		case "required":
		case "radio_req":
		case "radio_required":
		case "select_required":
		case "select_req": {
			switch (command) {
				case "req":
				case "required": {
					if(eval(pElement.value.length) == 0 || pElement.value.toLowerCase() == "required") {
						if (!pThis._hasErrors) pThis._hasErrors = true;
						switch (pBuildType) {
							case "buildMsg":
								Form_Validator.prototype.buildErrorMessage(pElement, pElement._errorMessage + " is required.");
								break;
							case "buildIconFlag":
								Form_Validator.prototype.buildFlag(pThis, pElement, true);
								break;
						}
					} else {
						Form_Validator.prototype.buildFlag(pThis, pElement, false);
					}
					break;
				}
				case "select_required":
				case "select_req": {
					if(pElement.selectedIndex == null) {
						throw new Error("Error: dontselect command for non-select Item");
						return false;
					}
					if(pElement.selectedIndex == eval(cmdvalue)) {
						if (!pThis._hasErrors) pThis._hasErrors = true;
						switch (pBuildType) {
							case "buildMsg":
								Form_Validator.prototype.buildErrorMessage(pElement, pElement._errorMessage + " is required.");
								break;
							case "buildIconFlag":
								Form_Validator.prototype.buildFlag(pThis, pElement, true);
								break;
						}
					} else {
						Form_Validator.prototype.buildFlag(pThis, pElement, false);
					}
					break;
				}
				case "radio_req": {
//					var chosen = false;
//					for (i=0; i<itemlength[itemlength_counter]; i++) {
//						if (this._form.elements[pElement.name] + "[" + i + "].checked")) {
//							chosen = true;
//						}
//					}
//					if (!chosen) {
//						if(!strError || strError.length==0) {
//							var mv = document.getElementsByName(pElement.name);
//							if (mv[0].getAttribute("label")) {
//								strError = mv[0].getAttribute("label") + " is a required field.";
//							} else {
//								strError = pElement.name + " : Required Field";
//							}
//						}
//					}
					break;
				}
			}
			break;
		}
		case "compare":
		case "comp": {
			if(pElement.value != "") {
				if(pElement.value != eval("document." + pElement._form.name + "." + cmdvalue + ".value")) {
					if (!pThis._hasErrors) pThis._hasErrors = true;
					switch (pBuildType) {
						case "buildMsg":
							Form_Validator.prototype.buildErrorMessage(pElement, pElement._errorMessage + "");
							break;
						case "buildIconFlag":
							Form_Validator.prototype.buildFlag(pThis, pElement, true);
							break;
					}
				} else {
					Form_Validator.prototype.buildFlag(pThis, pElement, false);
				}
			} else {
				if (!pThis._hasErrors) pThis._hasErrors = true;
				switch (pBuildType) {
					case "buildMsg":
						Form_Validator.prototype.buildErrorMessage(pElement, pElement._errorMessage + " is required.");
						break;
					case "buildIconFlag":
						Form_Validator.prototype.buildFlag(pThis, pElement, true);
						break;
				}
			}
			break;
		}
		case "maxlength":
		case "maxlen": {
			if(pElement.value != "") {
				if(eval(pElement.value.length) > eval(cmdvalue)) {
					if (!pThis._hasErrors) pThis._hasErrors = true;
					switch (pBuildType) {
						case "buildMsg":
							Form_Validator.prototype.buildErrorMessage(pElement, pElement._errorMessage + "");
							break;
						case "buildIconFlag":
							Form_Validator.prototype.buildFlag(pThis, pElement, true);
							break;
					}
				} else {
					Form_Validator.prototype.buildFlag(pThis, pElement, false);
				}
			} else {
				if (!pThis._hasErrors) pThis._hasErrors = true;
				switch (pBuildType) {
					case "buildMsg":
						Form_Validator.prototype.buildErrorMessage(pElement, pElement._errorMessage + " is required.");
						break;
					case "buildIconFlag":
						Form_Validator.prototype.buildFlag(pThis, pElement, true);
						break;
				}
			}
			break;
		}
		case "minlength":
		case "minlen": {
			if(pElement.value != "") {
				if(eval(pElement.value.length) < eval(cmdvalue)) {
					if (!pThis._hasErrors) pThis._hasErrors = true;
					switch (pBuildType) {
						case "buildMsg":
							Form_Validator.prototype.buildErrorMessage(pElement, pElement._errorMessage + "");
							break;
						case "buildIconFlag":
							Form_Validator.prototype.buildFlag(pThis, pElement, true);
							break;
					}
				} else {
					Form_Validator.prototype.buildFlag(pThis, pElement, false);
				}
			} else {
				if (!pThis._hasErrors) pThis._hasErrors = true;
				switch (pBuildType) {
					case "buildMsg":
						Form_Validator.prototype.buildErrorMessage(pElement, pElement._errorMessage + " is required.");
						break;
					case "buildIconFlag":
						Form_Validator.prototype.buildFlag(pThis, pElement, true);
						break;
				}
			}
			break;
		}
		case "alphanum":
		case "alphanumeric": {
			if(pElement.value != "") {
				var charpos = pElement.value.search("[^A-Za-z0-9 ]");
				if(pElement.value.length > 0 &&  charpos >= 0) {
					if (!pThis._hasErrors) pThis._hasErrors = true;
					switch (pBuildType) {
						case "buildMsg":
							Form_Validator.prototype.buildErrorMessage(pElement, pElement._errorMessage + "");
							break;
						case "buildIconFlag":
							Form_Validator.prototype.buildFlag(pThis, pElement, true);
							break;
					}
				} else {
					Form_Validator.prototype.buildFlag(pThis, pElement, false);
				}
			} else {
				if (!pThis._hasErrors) pThis._hasErrors = true;
				switch (pBuildType) {
					case "buildMsg":
						Form_Validator.prototype.buildErrorMessage(pElement, pElement._errorMessage + " is required.");
						break;
					case "buildIconFlag":
						Form_Validator.prototype.buildFlag(pThis, pElement, true);
						break;
				}
			}
			break;
		}
		case "num":
		case "numeric": {
			if(pElement.value != "") {
				var charpos = pElement.value.search("[^0-9]");
				if(pElement.value.length > 0 &&  charpos >= 0) {
					if (!pThis._hasErrors) pThis._hasErrors = true;
					switch (pBuildType) {
						case "buildMsg":
							Form_Validator.prototype.buildErrorMessage(pElement, pElement._errorMessage + "");
							break;
						case "buildIconFlag":
							Form_Validator.prototype.buildFlag(pThis, pElement, true);
							break;
					}
				} else {
					Form_Validator.prototype.buildFlag(pThis, pElement, false);
				}
			} else {
				if (!pThis._hasErrors) pThis._hasErrors = true;
				switch (pBuildType) {
					case "buildMsg":
						Form_Validator.prototype.buildErrorMessage(pElement, pElement._errorMessage + " is required.");
						break;
					case "buildIconFlag":
						Form_Validator.prototype.buildFlag(pThis, pElement, true);
						break;
				}
			}
			break;
		}
		case "numhyphen":
		case "numerichyphen": {
			if(pElement.value != "") {
				var charpos = pElement.value.search("[^0-9\-]");
				if(pElement.value.length > 0 &&  charpos >= 0) {
					if (!pThis._hasErrors) pThis._hasErrors = true;
					switch (pBuildType) {
						case "buildMsg":
							Form_Validator.prototype.buildErrorMessage(pElement, pElement._errorMessage + "");
							break;
						case "buildIconFlag":
							Form_Validator.prototype.buildFlag(pThis, pElement, true);
							break;
					}
				} else {
					Form_Validator.prototype.buildFlag(pThis, pElement, false);
				}
			} else {
				if (!pThis._hasErrors) pThis._hasErrors = true;
				switch (pBuildType) {
					case "buildMsg":
						Form_Validator.prototype.buildErrorMessage(pElement, pElement._errorMessage + " is required.");
						break;
					case "buildIconFlag":
						Form_Validator.prototype.buildFlag(pThis, pElement, true);
						break;
				}
			}
			break;
		}
		case "alphabetic":
		case "alpha": {
			if(pElement.value != "") {
				var charpos = pElement.value.search("[^A-Za-z]");
				if(pElement.value.length > 0 && charpos >= 0) {
					if (!pThis._hasErrors) pThis._hasErrors = true;
					switch (pBuildType) {
						case "buildMsg":
							Form_Validator.prototype.buildErrorMessage(pElement, pElement._errorMessage + "");
							break;
						case "buildIconFlag":
							Form_Validator.prototype.buildFlag(pThis, pElement, true);
							break;
					}
				} else {
					Form_Validator.prototype.buildFlag(pThis, pElement, false);
				}
			} else {
				if (!pThis._hasErrors) pThis._hasErrors = true;
				switch (pBuildType) {
					case "buildMsg":
						Form_Validator.prototype.buildErrorMessage(pElement, pElement._errorMessage + " is required.");
						break;
					case "buildIconFlag":
						Form_Validator.prototype.buildFlag(pThis, pElement, true);
						break;
				}
			}
			break;
		}
		case "alnumhyphen": {
			if(pElement.value != "") {
				var charpos = pElement.value.search("[^A-Za-z0-9\-_ ]");
				if(pElement.value.length > 0 &&  charpos >= 0) {
					if (!pThis._hasErrors) pThis._hasErrors = true;
					switch (pBuildType) {
						case "buildMsg":
							Form_Validator.prototype.buildErrorMessage(pElement, pElement._errorMessage + "");
							break;
						case "buildIconFlag":
							Form_Validator.prototype.buildFlag(pThis, pElement, true);
							break;
					}
				} else {
					Form_Validator.prototype.buildFlag(pThis, pElement, false);
				}
			} else {
				if (!pThis._hasErrors) pThis._hasErrors = true;
				switch (pBuildType) {
					case "buildMsg":
						Form_Validator.prototype.buildErrorMessage(pElement, pElement._errorMessage + " is required.");
						break;
					case "buildIconFlag":
						Form_Validator.prototype.buildFlag(pThis, pElement, true);
						break;
				}
			}
			break;
		}
		case "email": {
			if(pElement.value != "") {
				if(!validateEmailv2(pElement.value)) {
					if (!pThis._hasErrors) pThis._hasErrors = true;
					switch (pBuildType) {
						case "buildMsg":
							Form_Validator.prototype.buildErrorMessage(pElement, pElement._errorMessage + " is not a valid email.");
							break;
						case "buildIconFlag":
							Form_Validator.prototype.buildFlag(pThis, pElement, true);
							break;
					}
				} else {
					Form_Validator.prototype.buildFlag(pThis, pElement, false);
				}
			} else {
				if (!pThis._hasErrors) pThis._hasErrors = true;
				switch (pBuildType) {
					case "buildMsg":
						Form_Validator.prototype.buildErrorMessage(pElement, pElement._errorMessage + " is required.");
						break;
					case "buildIconFlag":
						Form_Validator.prototype.buildFlag(pThis, pElement, true);
						break;
				}
			}
			break;
		}
		case "lt":
		case "lessthan": {
			if(isNaN(pElement.value)) {
				if (!pThis._hasErrors) pThis._hasErrors = true;
			} else {
				if(pElement.value != "") {
					if(eval(pElement.value) >=  eval(cmdvalue)) {
						if (!pThis._hasErrors) pThis._hasErrors = true;
						switch (pBuildType) {
							case "buildMsg":
								Form_Validator.prototype.buildErrorMessage(pElement, pElement._errorMessage + " must be less than " + cmdvalue + ".");
								break;
							case "buildIconFlag":
								Form_Validator.prototype.buildFlag(pThis, pElement, true);
								break;
						}
					} else {
						Form_Validator.prototype.buildFlag(pThis, pElement, false);
					}
				} else {
					if (!pThis._hasErrors) pThis._hasErrors = true;
					switch (pBuildType) {
						case "buildMsg":
							Form_Validator.prototype.buildErrorMessage(pElement, pElement._errorMessage + " is required.");
							break;
						case "buildIconFlag":
							Form_Validator.prototype.buildFlag(pThis, pElement, true);
							break;
					}
				}
			}
			break;
		}
		case "gt":
		case "greaterthan": {
			if(isNaN(pElement.value)) {
				if (!pThis._hasErrors) pThis._hasErrors = true;
			} else {
				if(pElement.value != "") {
					if(eval(pElement.value) <=  eval(cmdvalue)) {
						if (!pThis._hasErrors) pThis._hasErrors = true;
						switch (pBuildType) {
							case "buildMsg":
								Form_Validator.prototype.buildErrorMessage(pElement, pElement._errorMessage + " must be greater than " + cmdvalue + ".");
								break;
							case "buildIconFlag":
								Form_Validator.prototype.buildFlag(pThis, pElement, true);
								break;
						}
					} else {
						Form_Validator.prototype.buildFlag(pThis, pElement, false);
					}
				} else {
					if (!pThis._hasErrors) pThis._hasErrors = true;
					switch (pBuildType) {
						case "buildMsg":
							Form_Validator.prototype.buildErrorMessage(pElement, pElement._errorMessage + " is required.");
							break;
						case "buildIconFlag":
							Form_Validator.prototype.buildFlag(pThis, pElement, true);
							break;
					}
				}
			}
			break;
		}
		case "regexp": {
			if(pElement.value != "") {
				if(!pElement.value.match(cmdvalue)) {
					if (!pThis._hasErrors) pThis._hasErrors = true;
					switch (pBuildType) {
						case "buildMsg":
							Form_Validator.prototype.buildErrorMessage(pElement, pElement._errorMessage + " must be in the form of ###-###-####.");
							break;
						case "buildIconFlag":
							Form_Validator.prototype.buildFlag(pThis, pElement, true);
							break;
					}
				} else {
					Form_Validator.prototype.buildFlag(pThis, pElement, false);
				}
			} else {
				if (!pThis._hasErrors) pThis._hasErrors = true;
				switch (pBuildType) {
					case "buildMsg":
						Form_Validator.prototype.buildErrorMessage(pElement, pElement._errorMessage + " is required.");
						break;
					case "buildIconFlag":
						Form_Validator.prototype.buildFlag(pThis, pElement, true);
						break;
				}
			}
			break;
		}
		case "check_req":
		case "check_required": {
			if(!pElement.checked) {
				if (!pThis._hasErrors) pThis._hasErrors = true;
				switch (pBuildType) {
					case "buildMsg":
						Form_Validator.prototype.buildErrorMessage(pElement, pElement._errorMessage + " is required.");
						break;
					case "buildIconFlag":
						Form_Validator.prototype.buildFlag(pThis, pElement, true);
						break;
				}
			} else {
				Form_Validator.prototype.buildFlag(pThis, pElement, false);
			}
			break;
		}
	}
}

function validateEmailv2(email) {
	// a very simple email validation checking. 
	// you can add more complex email checking if it helps 
	if(email.length<=0) {
		return true;
	}
	var splitted = email.match("^(.+)@(.+)$");
	if(splitted==null) return false;
	if(splitted[1]!=null) {
		var regexp_user = /^\"?[\w-_\.]*\"?$/;
		if(splitted[1].match(regexp_user)==null) return false;
	}
	if(splitted[2]!=null) {
		var regexp_domain = /^[\w-\.]*\.[A-Za-z]{2,4}$/;
		if(splitted[2].match(regexp_domain)==null) {
			var regexp_ip = /^\[\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\]$/;
			if(splitted[2].match(regexp_ip)==null) return false;
		}
		return true;
	}
	return false;
}

function removeAllFlags() {
	var _allElements = document.body.getElementsByTagName("div");
	for (var i=0; i<_allElements.length; i++) {
		for (var j=0; j<_allElements[i].attributes.length; j++) {
			if(_allElements[i].attributes.item(j).nodeName == 'class') {
				if(_allElements[i].attributes.item(j).nodeValue == 'pIcon') document.body.removeChild(_allElements[i]);
			}
		}
	}
}

function findPos(obj) {
	var curleft = curtop = 0;
	if (obj.offsetParent) {
		curleft = obj.offsetLeft
		curtop = obj.offsetTop
		while (obj = obj.offsetParent) {
			curleft += obj.offsetLeft
			curtop += obj.offsetTop
		}
	}
	return [curleft,curtop];
}

function setLyr(obj, lyr, offX, offY) {
	var coors = findPos(obj);
	var x = lyr;
	x.style.top = coors[1] + offY + 'px';
	x.style.left = coors[0] + offX + 'px';
}

function get_hex_color (r, g, b) {
	var hexstring = "0123456789ABCDEF";
	var hex_color = hexstring.charAt (Math.floor (r / 16)) + hexstring.charAt (r % 16) + hexstring.charAt (Math.floor (g / 16)) + hexstring.charAt (g % 16) + hexstring.charAt (Math.floor (b / 16)) + hexstring.charAt (b % 16);
	return hex_color;
}

Form_Validator.prototype.fadeToWhite = function() {
	blue += inc;
	if (blue >= 256) {
		cdeObj._errorMessageContainer.style.backgroundColor = "#FFF";
		if (!cdeObj._hasErrors) cdeObj._errorMessageContainer.style.display = "none";
		return;
	}
	cdeObj._errorMessageContainer.style.backgroundColor = get_hex_color(255, 255, blue);
	setTimeout("Form_Validator.prototype.fadeToWhite();", delay);
}
