var eInputRule = {None:0, AlphaNumerical:1, Float:2, Integer:3, PositiveFloat:4, PositiveInteger:5};   

function FieldValidator()
{
	this.validations = new Array();
		
	
	this.addValidation = function(oField, nInputRule, fValidation, sInvalidAlert)
	{
		if(!oField) throw "FieldValidator.addValidation --> Invalid field object (argument 1)";
		
		if(nInputRule == null || nInputRule > 5 || nInputRule < 0) nInputRule = eInputRule.None
		if(typeof fValidation != 'function') fValidation = null;
		if(!sInvalidAlert || trim(sInvalidAlert) == "") sInvalidAlert = null;
		
		var i = this.validations.length;
		this.validations[i] = new FieldProperties();
		this.validations[i].field = oField;
		this.validations[i].inputRule = nInputRule
		this.validations[i].validation = fValidation;
		this.validations[i].invalidAlert = sInvalidAlert;
		
		if(oField.tagName == "TEXTAREA" || (oField.tagName == "INPUT" && oField.type == "text"))
		{
			switch(nInputRule)
			{
				case eInputRule.AlphaNumerical:
					addEvent(oField,"keypress",function(e){_ValidatorAlphaNumericalOnly(false, e);});
					break;
				case eInputRule.Float:
					addEvent(oField,"keypress",function(e){_ValidatorNumbersOnly(false, false, e);});
					break;
				case eInputRule.Integer:
					addEvent(oField,"keypress",function(e){_ValidatorNumbersOnly(true, false, e);});
					break;
				case eInputRule.PositiveFloat:
					addEvent(oField,"keypress",function(e){_ValidatorNumbersOnly(false, true, e);});
					break;
				case eInputRule.PositiveInteger:
					addEvent(oField,"keypress",function(e){_ValidatorNumbersOnly(true, true, e);});
					break;
			}
		}
		return this.validations[i];
	}
	
	this.validate = function()
	{
		
		for(var i=0; i < this.validations.length; i++)
		{
			if(this.validations[i].validation && !this.validations[i].validation(getFieldValue(this.validations[i].field)))
			{
				if(this.validations[i].invalidAlert) alert(this.validations[i].invalidAlert);
				return false;
			}
		}
		return true;
	}
	
	function FieldProperties()
	{
		this.field = null;
		this.inputRule = null;
		this.invalidAlert = null;
		this.validation = null;
		return this;
	}
	
	

	function trim(str){
        return str.replace(/^\s*|\s*$/g,"");
	}
	
	function addEvent(obj, evType, fn)
	{
					
		if (obj.addEventListener)
		{   
			obj.addEventListener(evType, fn, false);
			return true;
		}
		else if (obj.attachEvent)
		{
			
			var r = obj.attachEvent("on"+evType, fn);
			return r;
		}
		else if(typeof obj["on"+evType]  != 'undefined')
		{
			obj["on"+evType] = fn;
			return  (obj["on"+evType] == fn);
		}
		else
		{
			return false;
		}
	}
	
	function getFieldValue(oField)
	{
		switch(oField.tagName)
		{
			case "SELECT":
				if( oField.selectedIndex == -1) return null;
				else return oField.options[oField.selectedIndex].value;
				break;
			case "TEXTAREA":
				return oField.value;
				break;
			case "INPUT":
				switch(oField.type)
				{
					case "text":
						return oField.value;
						break;
					case "file":
						return oField.value;
						break;
					case "checkbox":
						if(oField.checked) return oField.value;
						else return null;
						break;
					case "radio":
						if(oField.checked) return oField.value;
						else return null;
						break;
				}
				break;
		}		
	}
	

}


function _ValidatorAlphaNumericalOnly(bAllowSpaces,e)
{
	var oField = getEventElement(e);
	var nKey = getEventKey(e);
	var sKeyChar = String.fromCharCode(nKey);

	sKeyChar = String.fromCharCode(nKey).toLowerCase();

	if (nKey==null || nKey==0 || nKey==8 || nKey==9 || nKey==13 || nKey==27 || (!getEventShiftKey(e) && (nKey > 32 && nKey < 41) || nKey == 46))
		return true;
	else if ((String("abcdefghijklmnopqrstuvwxyz0123456789").indexOf(sKeyChar) > -1))
		return true;
	else if(bAllowSpaces && sKeyChar == " ")
		return true;
		
	cancelEvent(e);	
}

function _ValidatorNumbersOnly(bIntegerOnly, bPositiveOnly, e)
{
	var sDecimalChar = new Array(".",",");
	var oField = getEventElement(e);
	var nKey = getEventKey(e);
	var sKeyChar = String.fromCharCode(nKey);
	var oCaretPos = getCaretPosition(oField);
	var sSelText = oField.value.substr(oCaretPos.start, oCaretPos.length);
	
	
	if (nKey==0 || nKey==8 || nKey==9)
		return true;
	else if ((String("0123456789").indexOf(sKeyChar) > -1))
		return true;
	else if (sKeyChar == "-"  && !bPositiveOnly && oCaretPos.start == 0  && (sSelText.indexOf("-") > -1 || oField.value.indexOf("-") == -1))
		return true;
	else {
	    for(var i = 0;i < sDecimalChar.length;i++){
	        if (sKeyChar == sDecimalChar[i] && !bIntegerOnly && ( sSelText.indexOf(sDecimalChar[i]) > -1 || oField.value.indexOf(sDecimalChar[i]) == -1))
		        return true;
	    }
	}
	
	cancelEvent(e);	
}


function getCaretPosition(elm) {
	var r = {start:-1, length:-1};
	
	if (typeof elm.selectionStart != "undefined"){
		r.start = elm.selectionStart;
		r.length = elm.selectionEnd - elm.selectionStart;
	}
	else if (document.selection){
		r.start = Math.abs(document.selection.createRange().moveStart("character",-1000000));
		r.length = document.selection.createRange().text.length;
	}
	
	return r;
}

function cancelEvent(e)
{
	if(typeof e == 'undefined' && window.event) e = window.event;
	
	if(e.preventDefault){
		e.preventDefault();
		e.stopPropagation();
	}
	else{
		e.returnValue = false;
		e.cancelBubble = true;
	}
	
}

function getEventElement(e)
{

	if(typeof e == 'undefined' && window.event) e = window.event;
	
	if(typeof e.srcElement != 'undefined')
	{
		return e.srcElement;
	}
	else if(typeof e != 'undefined' && e != null)
	{
		return e.target;
	}
	
	return null;

}

function getEventKey(e)
{
	if(typeof e == 'undefined' && window.event) e = window.event;

	if (typeof e.charCode != 'undefined')
		return e.charCode;
	else if (e.keyCode)
		return e.keyCode;
	else
		return null;
		
		
}

function getEventShiftKey(e)
{
	return e.shiftKey;
}


