// JavaScript Document
// Original Auther and Credit goes out to Denny McEntire for a dyanimite implementation

function formValidate_v1(init) 
	{
		//alert("formValidate.init();");
		this.browserOK = false;
		// We don't need createElement, but this is a good DOM support check.
		if (document.createElement) this.browserOK = true;
		
		// Make a reference to the init form
		this.theForm = document.forms[init];
		this.parentRel = 0;
		
		if( formValidate_v1.arguments.length > 1 )
			{
				this.parentRel = formValidate_v1.arguments[1];		
			}
		
		// Array sets for storing references to form fields requiring specific types of checking
		this.req = new Array();		// required fields
		this.cc = new Array();		// credit cards
		this.eml = new Array();		// email
		this.zip = new Array();		// zip codes
		this.price = new Array();	// price
		this.lst = new Array();		// address list file type
		this.dsn = new Array(); 	// design file types
		this.img = new Array(); 	// image file types
		this.pw = new Array();		// password fields (assumed no more than one set per page - set being password field and confirm password field)
		this.len = new Array();		// character length
		this.quant = new Array();	// number quantity
		this.equal = new Array();	// equal value to another element (for verification fields)
		
		// Other variables
		this.focused = false;
		this.curLabel = new String();
		this.alertStrings = new Object();
		this.alertStrings.req = new String();
		this.alertStrings.cc = new String();
		this.alertStrings.eml = new String();
		this.alertStrings.zip = new String();
		this.alertStrings.lst = new String();
		this.alertStrings.dsn = new String();
		this.alertStrings.img = new String();
		this.alertStrings.pw = new String();
		this.alertStrings.len = new String();
		this.alertStrings.quant = new String();
		this.alertStrings.equal = new String();
		this.alertStrings.price = new String();
		
		this.collect();
	}
	
formValidate_v1.prototype.execute = function()
	{                           
		//alert(this.check())
		if(this.check()) this.theForm.submit();
		else {
            this.showAlert();
           // return false;
        }
	}
		
formValidate_v1.prototype.collect = function()
	{		
		//
		// Populate the checking array sets
		//
		var used = new Array();
		
		formElementLoop:
		for (var i = 0; i < this.theForm.elements.length; i++)
			{
				
				// Get the form element
				var curObj = new Object();
				curObj.el = this.theForm.elements[i];
				
				// Only insert a checkbox or radio set once
				if(curObj.el.type == "radio" || curObj.el.type == "checkbox")
					{
						for(var j = 0; j < used.length; j++)
							{
								if(curObj.el.name == used[j]) 
									{
										continue formElementLoop;
									}
							}
						used.push(curObj.el.name);					
					}
				
				// Get the propper className value
				var temp = curObj.el;
				for (var j = 0; j < this.parentRel; j++)
					{
						temp = temp.parentNode;
					}
				curObj.className = temp.className;
				//alert(curObj.className);
				// Perform the actual checks and array population
				// This is where the actual form class name comes into play with how the JS performs it's checks. 
				
				if(curObj.className.indexOf("req") > -1) this.req.push(curObj);
				
				if(curObj.className.indexOf("v-creditcard") > -1) this.cc.push(curObj);
				
				if(curObj.className.indexOf("v-email") > -1) this.eml.push(curObj);
				
				if(curObj.className.indexOf("v-zip") > -1) this.zip.push(curObj);
				
				if(curObj.className.indexOf("v-price") > -1) this.price.push(curObj);
				
				if(curObj.className.indexOf("v-list") > -1) this.lst.push(curObj);
				
				if(curObj.className.indexOf("v-design") > -1) this.dsn.push(curObj);
				
				if(curObj.className.indexOf("v-image") > -1) this.img.push(curObj);
				
				if(curObj.className.indexOf("_l_") > -1) this.len.push(curObj);
				
				if(curObj.className.indexOf("_q_") > -1) this.quant.push(curObj);
				
				if(curObj.className.indexOf("pw_") > -1) 
					{
						if(curObj.className.indexOf("_check") > -1) this.pw.check = curObj;
						else this.pw.main = curObj;
						continue;
					}
					
				if(curObj.className.indexOf("equal_") > -1) this.equal.push(curObj);
			}
	}

/* performs actual validation checking */
formValidate_v1.prototype.check = function()
	{
		var pass = true;

		// required
		for (var i = 0; i < this.req.length; i++)
			{
				if(!this.process_dep(this.req[i].className)) 
					{
						this.un_highlite(this.req[i].el);
						continue;
					}
				
				if(!this.process_req(this.req[i].el)) 
					{
						
						this.highlite(this.req[i].el);
						pass = false;

					}
				else this.un_highlite(this.req[i].el);
			}
			
		// credit card
		for (var i = 0; i < this.cc.length; i++)
			{
				if(!this.process_dep(this.cc[i].className))
					{
						this.un_highlite(this.cc[i].el);
						continue;
					}
				if(!this.is_not_empty(this.cc[i].el)) continue;
					
				if(!this.is_valid_cc(this.cc[i].el)) 
					{
						this.highlite(this.cc[i].el);
						pass = false;
					}
				else this.un_highlite(this.cc[i].el);
			}
			
		// email
		for (var i = 0; i < this.eml.length; i++)
			{
				if(!this.process_dep(this.eml[i].className))
					{
						this.un_highlite(this.eml[i].el);
						continue;
					}
				if(!this.is_not_empty(this.eml[i].el)) continue;

				if(!this.is_valid_email(this.eml[i].el)) 
					{
						this.highlite(this.eml[i].el);
						pass = false;
					}
				else this.un_highlite(this.eml[i].el);
			}
			
		// zip code
		for (var i = 0; i < this.zip.length; i++)
			{
				if(!this.process_dep(this.zip[i].className))
					{
						this.un_highlite(this.zip[i].el);
						continue;
					}
				if(!this.is_not_empty(this.zip[i].el)) continue;

				if(!this.is_valid_zip(this.zip[i].el)) 
					{
						this.highlite(this.zip[i].el);
						pass = false;
					}
				else this.un_highlite(this.zip[i].el);
			}
			
		// price
		for (var i = 0; i < this.price.length; i++)
			{
				if(!this.process_dep(this.price[i].className))
					{
						this.un_highlite(this.price[i].el);
						continue;
					}
				if(!this.is_not_empty(this.price[i].el)) continue;

				if(!this.is_valid_price(this.price[i].el)) 
					{
						this.highlite(this.price[i].el);
						pass = false;
					}
				else this.un_highlite(this.price[i].el);
			}
			
		// address list file extensions
		for (var i = 0; i < this.lst.length; i++)
			{
				if(!this.process_dep(this.lst[i].className))
					{
						this.un_highlite(this.lst[i].el);
						continue;
					}
				if(!this.is_not_empty(this.lst[i].el)) continue;

				if(!this.is_valid_list_ext(this.lst[i].el)) 
					{
						this.highlite(this.lst[i].el);
						pass = false;
					}
				else this.un_highlite(this.lst[i].el);
			}
			
		// design file extensions
		for (var i = 0; i < this.dsn.length; i++)
			{
				if(!this.process_dep(this.dsn[i].className))
					{
						this.un_highlite(this.dsn[i].el);
						continue;
					}
				if(!this.is_not_empty(this.dsn[i].el)) continue;

				if(!this.is_valid_design_ext(this.dsn[i].el)) 
					{
						this.highlite(this.dsn[i].el);
						pass = false;
					}
				else this.un_highlite(this.dsn[i].el);
			}
			
		// image file extensions
		for (var i = 0; i < this.img.length; i++)
			{
				if(!this.process_dep(this.img[i].className))
					{
						this.un_highlite(this.img[i].el);
						continue;
					}
				if(!this.is_not_empty(this.img[i].el)) continue;

				if(!this.is_valid_image_ext(this.img[i].el)) 
					{
						this.highlite(this.img[i].el);
						pass = false;
					}
				else this.un_highlite(this.img[i].el);
			}
			
		// character length restrictions
		for (var i = 0; i < this.len.length; i++)
			{
				if(!this.process_dep(this.len[i].className))
					{
						this.un_highlite(this.len[i].el);
						continue;
					}
				if(!this.is_not_empty(this.len[i].el)) continue;
				
				if(!this.process_len(this.len[i].el, this.len[i].className)) 
					{
						this.highlite(this.len[i].el);
						pass = false;
					}
				else this.un_highlite(this.len[i].el);
			}
			
		// quantity restrictions
		for (var i = 0; i < this.quant.length; i++)
			{
				if(!this.process_dep(this.quant[i].className))
					{
						this.un_highlite(this.quant[i].el);
						continue;
					}
				if(!this.is_not_empty(this.quant[i].el)) continue;
				
				if(!this.process_quant(this.quant[i].el, this.quant[i].className)) 
					{
						this.highlite(this.quant[i].el);
						pass = false;
					}
				else this.un_highlite(this.quant[i].el);
			}
			
		// password
		if(this.pw.main)
			{
				if(this.process_dep(this.pw.main.className) && this.is_not_empty(this.pw.main.el))
					{
						if(!this.is_valid_pw(this.pw.main.el, this.pw.main.className)) 
							{
								this.highlite(this.pw.main.el);
								this.highlite(this.pw.check.el);
								pass = false;
							}
						else if(this.pw.check.el && !this.check_pw_verify(this.pw.main.el, this.pw.check.el))
							{
								this.un_highlite(this.pw.main.el);
								this.highlite(this.pw.check.el);
								pass = false;
							}
						else 
							{
								this.un_highlite(this.pw.main.el);
								this.un_highlite(this.pw.check.el);
							}
					}
				else if(!this.process_dep(this.pw.main.className))
					{
						this.un_highlite(this.pw.main.el);
						this.un_highlite(this.pw.check.el);
					}
			}
			
		// equal field values (confirmation fields)
		for (var i = 0; i < this.equal.length; i++)
			{				
				if(!this.process_dep(this.equal[i].className))
					{
						this.un_highlite(equalEl);
						continue;
					}
				if(!this.is_not_empty(this.equal[i].el)) continue;
				
				var equalEl = this.theForm[this.get_equal_to_fieldname(this.equal[i].className)];
				
				if(!this.process_equal(this.equal[i].el, equalEl, this.equal[i].className)) 
					{
						this.highlite(equalEl);
						pass = false;
					}
				else this.un_highlite(equalEl);
			}
			

		this.focused = false;
		return pass;
		
	}
		
formValidate_v1.prototype.showAlert = function ()
	{
		alert(this.alertStrings.req + this.alertStrings.cc + this.alertStrings.eml + this.alertStrings.pw + this.alertStrings.zip + this.alertStrings.price + this.alertStrings.lst + this.alertStrings.dsn + this.alertStrings.img + this.alertStrings.len + this.alertStrings.quant + this.alertStrings.equal);
		
		// Reset necessary variables
		this.alertStrings.req = "";
		this.alertStrings.cc = "";
		this.alertStrings.eml = "";
		this.alertStrings.zip = "";
		this.alertStrings.price = "";
		this.alertStrings.lst = "";
		this.alertStrings.img = "";
		this.alertStrings.dsn = "";
		this.alertStrings.pw = "";
		this.alertStrings.len = "";
		this.alertStrings.quant = "";	
		this.alertStrings.equal = "";
	}

formValidate_v1.prototype.clearStructure = function ()
	{
		this.req = new Array();		
		this.cc = new Array();	
		this.eml = new Array();	
		this.zip = new Array();
		this.price = new Array();
		this.lst = new Array();
		this.pw = new Array();
		this.len = new Array();	
		this.quant = new Array();
		this.equal = new Array();
	}


// ***** Utility Function ***** //

formValidate_v1.prototype.process_req = function (el)
	{
		//alert(el.name.indexOf("div_"))
		if(el.type == "checkbox" || el.type == "radio") var good = this.is_checked(el);
		else if(el.type == "text" || el.type == "textarea" || el.type == "file" || el.type == "password") var good = this.is_not_empty(el);
		else if(el.name.indexOf("div_") > -1) var good = this.is_div_selected(el);
		else if(el.type.indexOf("select") > -1) var good = this.is_selected(el);

		//alert(el.name +"="+ good)

		if(!good) this.alertStrings.req = "Not all required fields were filled out.\n";
		return good;
	}

formValidate_v1.prototype.process_len = function (el, cn)
	{
		//alert(el.type);
		// Only check if a value has been entered
		if(!this.is_not_empty(el)) return true;
		
		var r = false;
		var t = this.parse_before(cn, "_l_");
		var n = Number(this.parse_after(cn, "_l_"));
		var n2 = "";
		
		if(t == "min") r = el.value.length >= n;
		if(t == "max") r = el.value.length <= n;
		else if(t == "exact") r = el.value.length == n;
		else if(t == "range") 
			{
				n2 = Number(this.parse_after(cn, "_l_" + n + "_"));
				r = el.value.length >= n && el.value.length <= n2;
			}
		if(!r)
			{
				if(n2 != "")
					{
						this.alertStrings.len += "The " + this.parse_label(this.parse_after(cn, "_l_" + n + "_" + n2 + "_")) + " field must have between " + n + " and " + n2 + " characters.\n";
					}
				else	this.alertStrings.len += "The " + this.parse_label(this.parse_after(cn, "_l_" + n + "_")) + " field must have " + this.parse_type(t) + " " + n + " characters.\n";
			}

		return r;
	}
	
formValidate_v1.prototype.process_quant = function (el, cn)
	{
		// Only check if a value exists
		if(!this.is_not_empty(el)) return true;
		
		var r = false;
		var t = this.parse_before(cn, "_q_");
		var n = this.parse_after(cn, "_q_");
		var n2 = "";
		// Make sure that this is a number and not text
		if(!this.is_num(el))
			{
				this.alertStrings.quant += "The \"" + this.parse_label(this.parse_after(cn, "_q_" + n + "_")) + "\" field must be a number.\n";
				return false;
			}else{
			
				return true;
			}
		
		
		
		//nguif(t == "min") r = Number(el.value) >= Number(n);
		//nguif(t == "max") r = Number(el.value) <= Number(n);
		//nguifelse if(t == "exact") r = Number(el.value) == Number(n);
		//nguifelse if(t == "range") 
		//nguif	{
		//nguif		var n2 = this.parse_after(cn, "_q_" + n + "_");
		//nguif		r = Number(el.value) >= Number(n) && Number(el.value) <= Number(n2);
		//nguif	}
		//nguifif(!r)
		//nguif	{
		//nguif		if(n2 != "")
		//nguif			{
		//nguif				this.alertStrings.quant +=  "The " + this.parse_label(this.parse_after(cn, "_q_" + n + "_" + n2 + "_")) + " field must be between " + n + " and " + n2 + ".\n";
		//nguif			}
		//nguif		else this.alertStrings.quant +=  "The " + this.parse_label(this.parse_after(cn, "_q_" + n + "_")) + " field must be " + this.parse_type(t) + " " + n + ".\n";
		//nguif	}
		//ngureturn r;
	}

formValidate_v1.prototype.process_dep = function (cn)
	{
		// Is there a dependency? If not, it passes
		if(cn.indexOf("dep") == -1) return true;
		
		// Check that the dependent checkbox or radio element is selected
		var fieldName = this.parse_after(cn, "dep_");
		var fieldValue = this.parse_after(cn, fieldName + "_");
		
		if(this.theForm[fieldName].length != "undefined")
			{
				
				// Loop through each element looking for the input with the correct value and is checked
				for(var i = 0; i < this.theForm[fieldName].length; i++)
					{
						if(this.theForm[fieldName][i].value == fieldValue && this.theForm[fieldName][i].checked) return true;
					}
				// No match found
				return false;
			}
		// If it's not a radio or checkbox, simply check the value
		else return this.theForm[fieldName].value == fieldValue;
	}

// Checks text fields, text areas, radio lists, or checkbox lists to make sure a value is present
formValidate_v1.prototype.is_not_empty = function (el)
	{
		//alert("formValidate.is_not_empty();");
		return el.value.replace(" ", "") == "" ? false : true;
	}

formValidate_v1.prototype.is_checked = function (el)
	{
		//alert("formValidate.radio_check");
		
		// Check each element in the set
		if(this.theForm[el.name].length)
			{
				for(var i = 0; i < this.theForm[el.name].length; i++)
					{
						if (this.theForm[el.name][i].checked) return true;
					}
			}
		else if (this.theForm[el.name].checked) return true;
		return false;
	}
	
formValidate_v1.prototype.is_selected = function (el)
	{
		//alert("value = "+el.value)
		return (el.value != "" ) ? true : false;	
	}
	
formValidate_v1.prototype.is_div_selected = function (el)
	{
		//alert("div = "+document.getElementById(el.name).value)
		return (document.getElementById(el.name).value != "" ) ? true : false;	
	}	
	
formValidate_v1.prototype.is_alphanum = function (el) 
	{
		// Only check if a value exists
		if(!this.is_not_empty(el)) return true;
		
		return this.validate_characters(el, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.");
	}
	
formValidate_v1.prototype.is_num = function (el) 
	{
		// Only check if a value exists
		if(!this.is_not_empty(el)) return true;
		
		return this.validate_characters(el, "0123456789.");
	}
	
formValidate_v1.prototype.is_valid_zip = function (el) 
	{
		// Only check if a value exists
		if(!this.is_not_empty(el)) return true;
		
		// Checks to make sure it is all numbers or "-", and that the length is between 5 and 10 characters long
		var good = (this.validate_characters(el, "0123456789-") && el.value.length >= 5 && el.value.length <= 10);
		if(!good) this.alertStrings.zip = "Zip codes must be in standard format (98888 or 98888-8888).\n";
		return good;
	}
	
formValidate_v1.prototype.validate_characters = function (el, okString)
	{
		//alert("formValidate.validate_characters : " + el.value.length);
		for (var i = 0; i < el.value.length; i++)
			{
				// Is the current indexed element value character found withing the okString? If not, return false.
				if(okString.indexOf(el.value.charAt(i)) == -1) return false;
			}
		return true;
	}

formValidate_v1.prototype.is_valid_email = function (el) 
	{
		//alert("is_valid_email");
		var RE = /\w+@\w+.+[.]\w{2,3}/;
		var good = RE.exec(el.value) != null; 
		
		if(!good) this.alertStrings.eml = "Your email address must be valid (someone@somewhere.???).\n";
		return good;
	}
	
formValidate_v1.prototype.is_valid_price = function (el) 
	{
		// This runs a regular expression check on the listing price to make
		// sure it's in an acceptable format.
		var price_re = /^([0-9]+|[0-9]{1,3}(,[0-9]{3})*)(\.[0-9]{2})?$/;
		var good = price_re.exec(el.value) != null;

		if(!good) this.alertStrings.price = "Please enter your price in standard currency format (1,000 or 1,000.00).\n";
		return good;
	}
	
//function to check Luhn-10 algo for CC numbers
formValidate_v1.prototype.is_valid_cc = function (el) 
	{
		//  guilty until proven Innocent
		var card_number = el.value;
		var GoodCard = false;
		var len = card_number.length;
	
		//  The Luhn formula works right to left, so reverse the number.
		var newstr = "";
		var y = len-1;
		while(y >= 0)
			{
				var newbit = card_number.substr(y,1);
				newstr = newstr+newbit;
				y = y-1;
			}
		
		//  Funky checking loop
		var Total = 0;
		var x = 0;
		while(x < len)
			{
				var digit = newstr.substr(x,1);
				var testdig = x / 2;
				
				//    If it's an odd digit, double it
				if (testdig != Math.floor(testdig)) 
					{
						digit = digit * 2;
						digit = digit.toString();
					}
		
				//    If the result is two digits, add them
				if (digit.length == 2)
					{
						var digitone = Math.abs(digit.substr(0,1));
						var digittwo = Math.abs(digit.substr(1,1));
						digit = digitone + digittwo;
					}
	
				//    Add the current digit, doubled and added if applicable, to the Total
				Total = Math.abs(Total);
				digit = Math.abs(digit);
				Total = Total + digit;
				x = x+1;
			}
	
		//  If the Total is evenly divisible by 10, it's cool!
		if(Total % 10 == 0 && this.is_num(el))
			{
				GoodCard = true;
			}
			
		if(!GoodCard) this.alertStrings.cc = "Please enter a valid credit card number.\n";
		return GoodCard;
	}
	
formValidate_v1.prototype.is_valid_pw = function (el, cn)
	{
		//alert(el);
		this.pw.length = this.parse_after(cn, "pw_");
		var good = el.value.length >= this.pw.length;
		if(!good) this.alertStrings.pw = "Your password must be at least " + this.pw.length + " characters long.\n";
		return good;
	}
	
formValidate_v1.prototype.check_pw_verify = function (tpw, tpwv)
	{
		var good = tpw.value == tpwv.value;
		if(!good) this.alertStrings.pw = "The password verification field does not match the password field.\n";
		return good;
	}
	
formValidate_v1.prototype.process_equal= function (el1, el2, cn)
	{
		var good = el1.value == el2.value;
		if(!good) 
			{
				var fieldName = this.parse_label(this.parse_after(cn, this.get_equal_to_fieldname(cn) + "_"));
				this.alertStrings.equal += "The " + fieldName + " verification field does not match the " + fieldName + " field.\n";
			}
		return good;
	}
	
formValidate_v1.prototype.is_valid_list_ext = function (el)
	{
		//alert(el.value.slice(el.value.lastIndexOf(".")));
		// Added .zip as an acceptable file type to allow variable
		// data jobs to come through the brand impact portals.  This
		// is not being stated anywhere and we do not want to notify
		// customers of this.
		var exts = new Array(".txt", ".csv", ".dbf", ".xls", ".zip");
		var good = this.string_match(el.value.slice(el.value.lastIndexOf(".")).toLowerCase(), exts);
		if(!good) this.alertStrings.lst = "Address list files must be of types: .txt, .csv, .dbf, or .xls.\n";
		return good;
	}
	
formValidate_v1.prototype.is_valid_design_ext = function (el)
	{
		//alert(el.value.slice(el.value.lastIndexOf(".")));
		var exts = new Array(".pdf", ".mif", ".fmv", ".ai", ".sdw", ".dxf", ".dwg", ".idw", ".rnd", ".bmp", ".rle", ".ico", ".cur", ".dib", ".prt", ".cgm", ".cmx", ".cdr", ".eps", ".xml", ".xsl", ".img", ".gem", ".gif", ".hp", ".hpgl", ".hgl", ".htm", ".html", ".css", ".gdf", ".pif", ".jpg", ".jpeg", ".jpe", ".fpx", ".pcd", ".drw", ".dsf", ".ppt", ".pps", ".pub", ".snp", ".doc", ".wps", ".psp", ".pcx", ".dcx", ".png", ".ps", ".prn", ".tif", ".vsd", ".wpd", ".wp5", ".zip");
		var good = this.string_match(el.value.slice(el.value.lastIndexOf(".")).toLowerCase(), exts);
		if(!good) this.alertStrings.dsn = "\nDesign files must be of types:\n .pdf, .mif, .fmv, .ai, .sdw, .dxf, .dwg, .idw, .rnd, .bmp, .rle, .ico, .cur, .dib, .prt, .cgm, .cmx, .cdr, .eps, .xml, .xsl, .img, .gem, .gif, .hp, .hpgl, .hgl, .htm, .html, .css, .gdf, .pif, .jpg, .jpeg, .jpe, .fpx, .pcd, .drw, .dsf, .ppt, .pps, .pub, .snp, .doc, .wps, .psp, .pcx, .dcx, .png, .ps, .prn, .tif, .vsd, .wpd, .zip, or .wp5\n";
		return good;
	}
	
formValidate_v1.prototype.is_valid_image_ext = function (el)
	{
		//alert(el.value.slice(el.value.lastIndexOf(".")));
		var exts = new Array(".pdf", ".bmp", ".eps", ".gif", ".jpg", ".jpeg", ".jpe", ".png", ".tif");
		var good = this.string_match(el.value.slice(el.value.lastIndexOf(".")).toLowerCase(), exts);
		if(!good) this.alertStrings.img = "\nImage files must be of types:\n .pdf, .bmp, .eps, .gif, .jpg, .jpeg, .jpe, .png, or .tif \n";
		return good;
	}
	
/* returns true if the string s is the same as one of the strings in the ok array */ 
formValidate_v1.prototype.string_match = function (s, ok)
	{
		//alert("formValidate.validate_stings");
		
		for (var i = 0; i < ok.length; i++)
			{
				if(s == ok[i]) return true;
			}
		return false;
	}
	
// Accepts a main string (st) and another string (key) that is a sub-string of st
// This method parses the number following key out and returns it. 
// eg: an st value of "pw_6" or "pw_6_req" returns 6 when the key is "pw_"
formValidate_v1.prototype.parse_after = function (st, key)
	{
		if(!st.indexOf(key)) return;
		
		var b = st.indexOf(key) + key.length;
		if(st.lastIndexOf("_") == b - 1) return st.slice(b);	
		else return st.slice(b, st.indexOf("_", b));
	}
formValidate_v1.prototype.parse_before = function (st, key)
	{
		if(!st.indexOf(key)) return;
		
		var b = st.indexOf(key);
		if(st.indexOf("_") == b) return st.slice(0, b);	
		else return st.slice(st.lastIndexOf("_", b - 1) + 1, b);
	}
formValidate_v1.prototype.parse_label = function (st)
	{
		while(st.indexOf("--") > -1)
			{
				st = st.replace("--", " ");
			}
		return st;
	}
formValidate_v1.prototype.parse_type = function (st)
	{
		switch (st) 
			{
				case "min": return "a minimum of";
				case "max": return "a maximum of";
				case "range": return "between";
				case "exact": return "exactly";
			}
		return false;
	}
formValidate_v1.prototype.get_equal_to_fieldname = function(cn)
	{
		return this.parse_after(cn, "equal_");
	}

// Highlites the incorrect fields and focuses the first one
formValidate_v1.prototype.highlite = function(el)
	{
		//alert(el.type);
		this.set_style(el, "#E00", "#E99");
		
		if(!this.focused)
			{
				el.focus();
				this.focused = true;
			}
	}
	
formValidate_v1.prototype.un_highlite = function(el)
	{
		//alert(el.type);
		this.set_style(el, "#DDD", "#EEE");
	}
	
formValidate_v1.prototype.set_style = function(el, p, s)
	{		
		if(el.type == "checkbox" || el.type == "radio")
			{
				if(this.theForm[el.name].length != undefined)
					{
						for(var i = 0; i < this.theForm[el.name].length; i++)
							{
								this.theForm[el.name][i].parentNode.style.border = "1px solid " + p;
							}
					}
				else
					{
						this.theForm[el.name].parentNode.style.border = "1px solid " + p;
					}
			}
		else
			{
				el.style.border = "1px solid " + p;
			}
	}
	
	
/***** Getter Setters *****/
formValidate_v1.prototype.get_req_array = function() { return this.req; };
formValidate_v1.prototype.get_cc_array = function() { return this.cc; };	
formValidate_v1.prototype.get_eml_array = function() { return this.eml; };	
formValidate_v1.prototype.get_zip_array = function() { return this.zip; };
formValidate_v1.prototype.get_lst_array = function() { return this.lst; };
formValidate_v1.prototype.get_pw_obj = function() { return this.pw; };
formValidate_v1.prototype.get_len_array = function() { return this.len; };	
formValidate_v1.prototype.get_quant_array = function() { return this.quant; };

formValidate_v1.prototype.set_req_array = function(n) { this.req = n; };
formValidate_v1.prototype.set_cc_array = function(n) { this.cc = n; };	
formValidate_v1.prototype.set_eml_array = function(n) { this.eml = n; };	
formValidate_v1.prototype.set_zip_array = function(n) { this.zip = n; };
formValidate_v1.prototype.set_lst_array = function(n) { this.lst = n; };
formValidate_v1.prototype.set_pw_obj = function(n) { this.pw = n; };
formValidate_v1.prototype.set_len_array = function(n) { this.len = n; };	
formValidate_v1.prototype.set_quant_array = function(n) { this.quant = n; };

//-->

