/**
 * @author alex
 */
var rules = null;
function EComm(formname) {
	if (formname != '') {
		p = document.getElementsByName(formname);
		this._form = p[0];
	} else {
		alert('2');
		this._form = document.forms[0];
	}
}

EComm._old_text = "";

EComm.prototype.initFocus = function() {
	if (this._form) {
		for (var i=0; i <this._form.elements.length; i++) {
			if (this._form.elements[i].type != 'hidden') {
				this._form.elements[i].focus();
				var _this = this;
				this._form.onsubmit = function () {
					return _this._validate(); 
				}
				break;
			}
		}
	} 
}

EComm.prototype.getField = function(name) {
	if (this._form) {
		return this._form.elements[name]; 
	}
	return null; 
}

EComm.prototype._showError = function(msg) {
	var efield = document.getElementById("form_intro");
	if (!efield) return false;
	this._old_text = efield.innerHTML;
	efield.innerHTML = "Error: " + msg;
	efield.className = "form_intro_error"; 
}

EComm.prototype._clearError = function() {
	var efield = document.getElementById("form_intro");
	if (!efield) return false;
	efield.innerHTML = this._old_text;
	efield.className = "form_intro";
}

EComm.prototype.setRules = function (rules, rules_func) {
	this._rules = rules;
	this._rules_func = rules_func; 
}

EComm.prototype._validate = function () {
	if (!this._form || !this._rules) {
		return true; 
	}
	
	var _this = this;
	
	function validationFailed(msg, where) {
		_this._showError(msg);
		where.focus();
		/*
		where.onblur = function() {
			_this._clearError();
		}*/ 
	}
	
	/* do the validation stuff here*/
	
	for (var elem = 0; elem < this._form.elements.length; elem++) {
		 
		if (this._form.elements[elem].id && this._rules[this._form.elements[elem].id]) {
			var element = this._form.elements[elem];
			var rule = this._rules[this._form.elements[elem].id]; 
			
			switch (rule.rule) {
				case "email":
					var val = element.value;
					var invalid = false;
					if (val == "") {
						invalid = true; 
					}
					// a@a.ru
					if (val.indexOf("@") < 1) {
						invalid = true;
					}
					if (val.indexOf(".") < 0) {
						invalid = true;
					}
					if (val.length < 7) {
						invalid = true;
					}
					
					if (invalid) {
						validationFailed(rule.message, element);
						return false; 
					}
					break;
				case "text":
					if (element.value == "") {
						validationFailed(rule.message, element);
						return false;
					}
					break;
				case "integer":
					if (element.value == "" || !isNum(element.value)) {
						validationFailed(rule.message, element);
						return false;
					}
					break;
				case "ccnum":
					if (element.value == "" || !isNum(element.value) || !luhnCheck(element.value)) {
						validationFailed(rule.message, element);
						return false;
					}
					break;
				default : 
					alert(rule.rule + "isn't known validation rule");
					break; 
			} 
		} 
	}
	
	// do custom validation if necessary
	if (this._rules_func) {
		var res = this._rules_func.call(this, this);
		if (res) {
			/* 
			this._showError(res["message"]);
			res["field"].focus();
			var _this = this;
			res["field"].onblur = function() {
				_this._clearError(); 
			}*/
			validationFailed(res["message"], res["field"]);
			return false; 
		} 
	}
	return true; 
}



function init(formname) {
	var ec = new EComm(formname);
	ec.initFocus();
	if (rules) {
		if (rules_func) {
			ec.setRules(rules, rules_func);
		} else {
			ec.setRules(rules); 
		}
	}
}

function isNum(argvalue) {
	argvalue = argvalue.toString();
	
	if (argvalue.length == 0)
		return false;
	
	for (var n = 0; n < argvalue.length; n++)
		if (argvalue.substring(n, n+1) < "0" || argvalue.substring(n, n+1) > "9")
			return false;
	
	return true;
}

/*************************************************************************\
boolean luhnCheck([String cardNumber])
return true if cardNumber pass the luhn check else return false.
Reference: http://www.ling.nwu.edu/~sburke/pub/luhn_lib.pl
*************************************************************************/
function luhnCheck(cardNumber) {
	
	if (! isNum(cardNumber)) {
		return false;
	}
	
	var no_digit = cardNumber.length;
	var oddoeven = no_digit & 1;
	var sum = 0;
	
	for (var count = 0; count < no_digit; count++) {
		var digit = parseInt(cardNumber.charAt(count));
		if (!((count & 1) ^ oddoeven)) {
			digit *= 2;
			if (digit > 9)
				digit -= 9;
		}
		sum += digit;
	}
	if (sum % 10 == 0)
		return true;
	else
		return false;
}

/*************************************************************************\
HTNL Input formatting (us digits format)
*************************************************************************/
function filterInput(e, field) { //onkeyup="filterInput(this);"
	var key;
	if (window.event) {
			   key = e.keyCode;
	}
	else if (e.which)
	{
			   key = e.which;
	}
	var ch = String.fromCharCode(key);
	var input_string = formatToNumber(field.value);
	field.value = formatNumber(input_string);
}

function formatToNumber(in_str) {
	return in_str.replace(/[^\d]+/gi, '');
}

function formatNumber(in_str) {
	var out_str = ""; 
	var count = 0;
	for (var i=in_str.length-1; i>=0; i--) {
			   if (count == 3) {
						   count = 0;
						   out_str = "," + out_str;
			   }
			   out_str = in_str.charAt(i) + out_str;
			   count++;
	}
	return out_str;
}
/*************************************************************************\
HTNL Input formatting (us phone format '(111) 111-1111')
*************************************************************************/
function filterPhoneInput(e, field) { //onkeyup="filterInput(this);"
	var key;
	if (window.event) {
			   key = e.keyCode;
	}
	else if (e.which)
	{
			   key = e.which;
	}
	var ch = String.fromCharCode(key);
	var input_string = formatToNumber(field.value);
	field.value = formatPhone(input_string);
}

function formatPhone(in_str) {
	var out_str = ""; 
	var count = 0;
	var lenght = in_str.length-1;
	if ( lenght > 9) {
		lenght = 9;
	}
	for (var i=0; i<=lenght; i++) {
			   switch (count) {
				   case 0:
						out_str = "(" + in_str.charAt(count);
						count = 1;
						break;
					case 3: 
						out_str = out_str + ") " + in_str.charAt(count);
						count = 4;
						break;
					case 6: 
						out_str = out_str + " " + in_str.charAt(count);
						count = 7;
						break;
					default:
					   out_str = out_str + in_str.charAt(count);
					   count++;
					   break;
			   }
	}
	return out_str;
}

/*************************************************************************\
HTNL Input formatting (us phone body format - '111-4567')
*************************************************************************/

function filterPhoneBodyInput(e, field) { //onkeyup="filterPhoneBodyInput(this);"
	var key;
	if (window.event) {
			   key = e.keyCode;
	}
	else if (e.which)
	{
			   key = e.which;
	}
	var ch = String.fromCharCode(key);
	var input_string = formatToNumber(field.value);
	field.value = formatPhoneBody(input_string);
}

function formatPhoneBody(in_str) {
	var out_str = ""; 
	var count = 0;
	var lenght = in_str.length-1;
	if ( lenght > 6) {
		lenght = 6;
	}
	for (var i=0; i<=lenght; i++) {
			   switch (count) {
					case 3: 
						out_str = out_str + " " + in_str.charAt(count);
						count = 4;
						break;
					default:
					   out_str = out_str + in_str.charAt(count);
					   count++;
					   break;
			   }
	}
	return out_str;
}
