var vdata = {"first_name":{"field":"first_name","label":"First Name","message":"","rules":[{"vfunction":"set","parameters":null}]},
"address":{"field":"address","label":"Address","message":"","rules":[{"vfunction":"set","parameters":null}]},
"city":{"field":"city","label":"City","message":"","rules":[{"vfunction":"set","parameters":null}]},
"state":{"field":"state","label":"State","message":"","rules":[{"vfunction":"set","parameters":null}]},
"zip":{"field":"zip","label":"Zip Code","message":"","rules":[{"vfunction":"set","parameters":null}]},
"phone":{"field":"phone","label":"Phone","message":"","rules":[{"vfunction":"set","parameters":null}]},
"email":{"field":"email","label":"E-Mail","message":"","rules":[{"vfunction":"set","parameters":null},{"vfunction":"email","parameters":null}]},
"amount":,
"cardholder_name":{"field":"cardholder_name","label":"Name of card holder","message":"","rules":[{"vfunction":"set","parameters":null}]},
"cc_type":{"field":"cc_type","label":"Card Type","message":"","rules":[{"vfunction":"set","parameters":null}]},
"exp[0]":{"field":"exp[0]","label":"Expiration Month","message":"","rules":[{"vfunction":"set","parameters":null}]},
"exp[1]":{"field":"exp[1]","label":"Expiiration Year","message":"","rules":[{"vfunction":"set","parameters":null}]},
"card_number":{"field":"card_number","label":"Card Number","message":"","rules":[{"vfunction":"set","parameters":null}]},
"security":{"field":"security","label":"Card Code","message":"","rules":[{"vfunction":"set","parameters":null}]}
};			
//################ BEGIN UTILITY CODE ###################
		/*******************************************************
* Foundation Framework 1.0
* License:
* This is commercial software.
* Any use, publication or duplication without
* express permission by the author is prohibited.
* This notice must accompany all copies of this 
* software
* copyright 2006
********************************************************
* @author Chris C. Root
* hammer65@gmail.com
******************************************************/
	function so_utility()
	{
			this.isNumeric = function(value)
			{
			   var strValidChars = "0123456789.";
			   var strChar;
			   var blnResult = true;
			
			   if (value.length == 0) return false;
			
			   //  test strString consists of valid characters listed above
				  for (i = 0; i < value.length; i++)
				  {
				  strChar = value.charAt(i);
					 if (strValidChars.indexOf(strChar) == -1)
					 {
					 blnResult = false;
					 break;
					 }
				  }
				  return blnResult;
			}
			this.so_extend = function(element,ans)
			{
				var tagName = element.tagName.toLowerCase();
				var aName = '';
				if(typeof ans != "undefined")
				{
					aName = ans;
				}
				else
				{
					aName = 'so_' + tagName;
				}
				if(window[aName] && element)
				{
					var a = window[aName];
					var aObj = new a();
					for(att in aObj)
					{
						element[att] = aObj[att];
					}
				}
				return element;
			}
			this.idGen = function(type,strLen)
			{
				if(typeof strLen == 'undefined')
				{
					strLen = 8;
				}
				var vals = new Array()
				if(type == "d")
				{
					vals[0] = new Array(1,2,5,4,6,8,7,3,5,4,6,5,1,3,2,0,5);
					vals[1] = new Array(3,5,4,1,9,8,6,5,4,6,5,7,8,1,0,2,3,1,2);
					vals[2] = new Array(5,4,5,6,1,2,3,6,5,8,9,7,4,5,3,2);
					vals[3] = new Array(1,2,1,5,4,5,6,8,5,4,5,8,7,9,2,3);
					vals[4] = new Array(6,2,3,5,4,8,9,5,1,2,2,4,3,1,2,0,3);
				}
				else if(type == "c")
				{
					vals[0] = new Array("f","k","s","h","i","e","q","p","c","p","c","e","y","t","g","h");
					vals[1] = new Array("p","n","b","z","w","n","r","v");
					vals[2] = new Array("z","o","e","y","f","b","w","v","n","s");
					vals[3] = new Array("a","p","u","w","c","r","k","n","h","m","d","g");
					vals[4] = new Array("b","m","h","a","p","n","b","m","h","x","w","c","r","k");
				}
				else
				{
					vals[0] = new Array(1,2,5,4,5,6,"f","s","e","t","u","4","g","c","k");
					vals[1] = new Array("p","n","b","5","h","8","z","9","n","x","v");
					vals[2] = new Array("z","0","e","1","f","7","w","v","n","s");
					vals[3] = new Array(5,4,6,9,7,8,0,"a","q","w","y","b","m",2,3);
					vals[4] = new Array(7,8,0,"a","q","w","y","5","h","8","z","9");
					vals[5] = new Array("e","t","u","4","g",9,7,8,0,"s","d","j",5,"x");
					vals[6] = new Array("!","z","g","n","w",9,4,7,"p",0,"a","q","w");
				}
				str = "";
				len = vals.length - 1;
				for(var i = 0;i < strLen;i++)
				{
					var num = Math.random()*(len-1);
					num = Math.round(1+num);
					num = num - 1;
					var num2 = Math.random()*((vals[num].length-1)-1);
					num2 = Math.round(1+num2);
					str += vals[num][num2];
				}
				return str
			}			
			this.extend = function(element,ans)
			{
				var aName = '';
				if(typeof ans != "undefined")
				{
					aName = ans;
				}
				else
				{
					var tagName = element.tagName.toLowerCase();
					aName = 'so_' + tagName;
				}
				if(window[aName] && element)
				{
					var a = window[aName];
					var aObj = new a();
					for(att in aObj)
					{
						element[att] = aObj[att];
					}
				}
				return element;
			}
			
			this.getElement = function(id,ans)
			{
				var el = document.getElementById(id);
				if(typeof el != 'undefined')
				{
					el = this.so_extend(el,ans);
					el.init();
					return el;
				}
			}
	}
	
	var utility = new so_utility();
//############## BEGIN VALIDATION CODE ##################
function validForm()
{
	this.errors = new Array();
	this.errorFields = new Array();
	this.messages = new Array();
	this.vfields = new Object();
	this.init = function(data)
	{
		var el = this.elements;
		for(v in data)
		{
			if(typeof el[v] != 'undefined')
			{
				utility.extend(el[v],'formElement');
				el[v].init(data[v]);
				el[v].parentForm = this;
				this.vfields[v] = el[v];
				this.errors[this.errors.length] = 0;
				this.errorFields[this.errorFields.length] = v;
			}
		}
	}
	
	this.validate = function()
	{
		this.errors = new Array();
		this.messages = new Array();
		if(this.errorFields.length != 0)
		{
			var el = this.vfields;
			//console.log(this.errorFields.length);
			for(var i = 0;i < this.errorFields.length;i++)
			{
				this.errors[i] = el[this.errorFields[i]].validate();
				//console.log(el[this.errorFields[i]].name);
				if(!this.errors[i])
				{
					this.messages[this.messages.length] = el[this.errorFields[i]].message;
				}
				//console.log(i + '----');
			}
			if(this.in_array(0,this.errors))
			{
				alert(this.messages.join('\n'));
				return false;
			}
			else
			{
				return true;
			}
		}
		else
		{
			return true;
		}
	}
	
	this.isValid = function(rule,valObj)
	{
		var func = rule.vfunction.toLowerCase();
		var parameters = rule.parameters;
		switch(func)
		{
			case 'notempty':
				return this.notEmpty(valObj.value);
				break;
			case 'set':
				return this.notEmpty(valObj.value);
				break;
			case 'number':
				return this.isNumber(valObj.value);
				break;
			case 'checked':
				var rv = 0;
				if(typeof valObj.state != 'undefined')
				{
					if(valObj.state)
					{
						rv = 1;
					}
				}
				else
				{
					for(var i = 0;i < valObj.length;i++)
					{
						if(valObj[i].state)
						{
							return 1;
						}
					}
				}
				return rv;
				break;
			case 'one':
				return this.one(valObj);
				break;
			case 'not':
				return this.not(valObj.value,parameters);
				break;
			case 'is':
				return this.is(valObj.value,parameters);
				break;
			case 'depend':
				return 1;
				//for future upgrade
				//return this.depend(value,parameters);
				break;
			case 'ssn':
				return this.validSSN(valObj.value);
				break;
			case 'credit':
				return this.validCC(valObj.value);
				break;
			case 'email':
				return this.validEmail(valObj.value);
				break;
			case 'number':
				return this.isNumber(valObj.value);
				break;
		}
	}
	
	this.isNumber = function(val)
	{
		if(this.notEmpty(val))
		{
			val = val.replace('.','');
			var reg = /^\d+$/;
			if(reg.test(val))
			{
				return 1;
			}
			else
			{
				return 0;	
			}
		}
		else
		{
			return 1	
		}
	}

	this.in_array = function(needle,array)
	{
		var flat = array.join('|');
		if(flat.indexOf(needle) != -1)
		{
			return true;
		}
		else
		{
			return false;
		}
	}
	
	//####### BEGIN VALIDATION FUNCTIONS #################
	
	this.notEmpty = function(value)
	{
		var ret = 0;
		if(value.replace(/^\s/g,'').replace(/$\s/g).length!=0)
		{
			ret = 1;
		}
		return ret;
	}
	
	this.one = function(vObj)
	{
		for(var i = 0;i < vObj.length;i++)
		{
			if(vObj[i].state)
			{
				return 1;
			}
		}
		return 0;
	}
	
	this.not = function(value,parameters)
	{
		if(typeof parameters.type == 'undefined' || parameters.type != 'exp')
		{
			if(value != parameters.notValue)
			{
				return 1;
			}
			else
			{
				return 0;
			}
		}
		else
		{
			var reg = new RegExp(parameters.notValue);
			if(value.match(reg))
			{
				return 0;
			}
			else
			{
				return 1;
			}
		}
	}
	
	this.is = function(value,parameters)
	{
		if(typeof parameters.type == 'undefined' || parameters.type != 'exp')
		{
			if(value == parameters.isValue)
			{
				return 1;
			}
			else
			{
				return 0;
			}
		}
		else if(parameters.type == 'exp')
		{
			reg = new RegExp(parameters.isValue);
			if(value.match(reg))
			{
				return 1;
			}
			else
			{
				return 0;
			}
		}
	}
	
	this.validCC = function(s)
	{
		// remove non-numerics
		var v = "0123456789";
		var w = "";
		for (i=0; i < s.length; i++)
		{
			x = s.charAt(i);
			if (v.indexOf(x,0) != -1)
			{
				w += x;
			}
		}
		// validate number
		j = w.length / 2;
		if (j < 6.5 || j > 8 || j == 7) return 0;
		k = Math.floor(j);
		m = Math.ceil(j) - k;
		c = 0;
		for (i=0; i<k; i++)
		{
			a = w.charAt(i*2+m) * 2;
			c += a > 9 ? Math.floor(a/10 + a%10) : a;
		}
		for (i=0; i<k+m; i++) c += w.charAt(i*2+1-m) * 1;
		if(c%10 == 0)
		{
			return 1;
		}
		else
		{
			return 0;
		}
	}
	
	this.validSSN = function(ssn)
	{
		var matchArr = ssn.match(/^(\d{3})-?\d{2}-?\d{4}$/);
		var numDashes = ssn.split('-').length - 1;
		if (matchArr == null || numDashes == 1)
		{
			return 0;
		}
		else if (parseInt(matchArr[1],10)==0)
		{
			return 0;
		}
		else
		{
			return 1;
		}
	}
	
	this.validEmail = function(emailStr)
	{
		if(!this.notEmpty(emailStr))
		{
			return true;
		}
		var checkTLD=1;
		var knownDomsPat=/^(com|net|org|edu|int|mil|gov|arpa|biz|aero|name|coop|info|pro|museum)$/;
		var emailPat=/^(.+)@(.+)$/;
		var specialChars="\\(\\)><@,;:\\\\\\\"\\.\\[\\]";
		var validChars="\[^\\s" + specialChars + "\]";
		var quotedUser="(\"[^\"]*\")";
		var ipDomainPat=/^\[(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\]$/;
		var atom=validChars + '+';
		var word="(" + atom + "|" + quotedUser + ")";
		var userPat=new RegExp("^" + word + "(\\." + word + ")*$");
		var domainPat=new RegExp("^" + atom + "(\\." + atom +")*$");
		var matchArray=emailStr.match(emailPat);
		if (matchArray==null)
		{
			return 0;
		}
		var user=matchArray[1];
		var domain=matchArray[2];
		for (i=0; i<user.length; i++)
		{
			if (user.charCodeAt(i)>127)
			{
				return 0;
			}
		}
		for (i=0; i<domain.length; i++)
		{
			if (domain.charCodeAt(i)>127)
			{
				return 0;
			}
		}
		if (user.match(userPat)==null)
		{
			fobj.error_text = "The email username doesn't seem to be valid.";
			return 0;
		}
		var IPArray=domain.match(ipDomainPat);
		if (IPArray!=null)
		{
			for (var i=1;i<=4;i++)
			{
				if (IPArray[i]>255)
				{
				fobj.error_text = "Emal destination IP address is invalid!";
				return 0;
				}
			}
		return 1;
		}
		var atomPat=new RegExp("^" + atom + "$");
		var domArr=domain.split(".");
		var len=domArr.length;
		for (i=0;i<len;i++)
		{
			if (domArr[i].search(atomPat)==-1)
			{
				return 0;
		   }
		}
		if (checkTLD && domArr[domArr.length-1].length!=2 && 
	domArr[domArr.length-1].search(knownDomsPat)==-1)
		{
			fobj.error_text = "The email address must end in a well-known domain or two letter " + "country.";
			return 0;
		}
		if (len<2)
		{
			fobj.error_text = "This address is missing a hostname!";
			return 0;
		}
		return 1;
	}
	
	//################# END VALIDATION FUNCTIONS ###########################
}

function formElement()
{
	this.rules = new Array();
	this.label = '';
	this.errorText = '';
	this.valid = 1;
	this.message = ' Is required.';
	this.parentForm = null;
	this.init = function(data)
	{
		if(typeof data.message != 'undefined' && data.message != null && data.message != '')
		{
			this.message = data.message;
		}
		else
		{
			if(typeof data.label != 'undefined' && data.label != null && data.label != '')
			{
				this.label = data.label;
			}
			else
			{
				this.label = this.getName().replace('_',' ');
			}
			this.message = this.label + this.message;
		}
		for(var i = 0;i < data.rules.length;i++)
		{
			this.rules[i] = data.rules[i];
		}
	}
	
	this.setError = function()
	{
		this.errorText = this.label + ' ' + this.message;
	}
	
	this.getUsableValue = function(el)
	{
		if(typeof el == 'undefined')
		{
			el = this;
		}
		if(typeof el.tagName != 'undefined')
		{
			var tagName = el.tagName;
			var ret = new Object();
			switch(tagName.toLowerCase())
			{
				case 'input':
					switch(el.type)
					{
						case 'text':
							ret.value = el.value;
							state = false;
							if(el.value.replace(/^\s/g,'').replace(/$\s/g).length!=0)
							{
								ret.state = true;
							}
							return ret;
							break;
						case 'checkbox':
							ret.value = el.value;
							ret.state = 0;
							if(el.checked)
							{
								ret.state = 1;
							}
							return ret;
							break;
						case 'radio':
							ret.value = el.value;
							ret.state = 0;
							if(el.checked)
							{
								ret.state = 1;
							}
							return ret;
							break;
					}
					break;
				case 'textarea':
					ret.value = el.value;
					state = false;
					if(el.value.replace(/^\s/g,'').replace(/$\s/g,'').length != 0)
					{
						ret.state = true;
					}
					return ret;
					break;
				case 'select':
					if(el.getAttribute('multiple') == 'multiple')
					{
						var ret = new Array();
						var len;
						for(var i = 0;i < el.options.length;i++)
						{
							len = ret.length;
							ret[len] = new Object();
							ret[len].value = el.options[i].value;
							ret[len].state = el.options.selected;
						}
					}
					else
					{
						ret.value = el.options[el.selectedIndex].value;
						state = false;
						if(el.options[el.selectedIndex].value != '')
						{
							state = true;
						}
						ret.state = state;
						return ret;
					}
					break;
			}
		}
		else
		{
			if(typeof el.item != 'undefined')
			{
				var ret = new Array();
				for(var i = 0;i < el.length;i++)
				{
					ret[i] = this.getUsableValue(el.item(i)); 
				}
				return ret;
			}
		}
	}
	
	this.validate = function()
	{
		if(this.rules.length > 0)
		{
			this.unHighlight();
			var result = new Array();
			for(var i = 0;i < this.rules.length;i++)
			{
				result[i] = this.parentForm.isValid(this.rules[i],this.getUsableValue());
			}
			if(this.in_array(0,result))
			{
				this.setError();
				this.highlight();
				this.valid = 0;
				return 0;
			}
			else
			{
				this.valid = 1;
				return 1;
			}
		}
		else
		{
			this.valid = 1;
			return 1;
		}
	}
	
	this.in_array = function(needle,array)
	{
		var flat = array.join('|');
		if(flat.indexOf(needle) != -1)
		{
			return true;
		}
		else
		{
			return false;
		}
	}
	
	this.getName = function()
	{
		if(typeof this.name != 'undefined')
		{
			return this.name;
		}
		else if(typeof this.item != 'undefined' && this.length != 0)
		{
			return this.item(0).name;
		}
		else
		{
			return '';
		}
	}
	
	this.highlight = function()
	{
		if(typeof this.style != 'undefined')
		{
			this.style['border'] = '1px solid';
			this.style.borderColor = '#FF0000';
		}
	}
	
	this.unHighlight = function()
	{
		if(typeof this.style != 'undefined')
		{
			this.style.border = '1px solid';
			this.style.borderColor = '#000000';
		}
	}
}				
var v = utility.extend(document.getElementById('vform'),'validForm');
v.init(vdata);		