var ncValidation = new Validation();
function Validation(){
	// force functions return true if they alter the value of the input field
	this.ForceNumber = function(poInput, dps, pMin, pMax, p_lFormatType){
		return _ForceAndMoveCaret(poInput, _ValidateNumber(poInput.value, dps, true, pMin, pMax, p_lFormatType));
	};
	
	this.ForceInteger=_ForceInteger;
	
	this.ForcePercentage=_ForcePercentage;
	
	this.CheckAgainstExp = function(pInput, pExp){
		return _ForceAndMoveCaret(pInput, pInput.value.replace(pExp, ""));
	};
	
	function _ForceInteger(pInput, pAllowNegs, pMin, pMax){
		return _ForceAndMoveCaret(pInput, _ValidateNumber(pInput.value, 0, pAllowNegs, pMin, pMax));
	}
	
	function _ForcePercentage(poInput, dps){
		var ln = _ValidateNumber(poInput.value, dps);
		ln = ln.replace(/^(\d{2})\d*(\.\d*)?$/, "$1$2");
		return _ForceAndMoveCaret(poInput, ln);
	}
	
	function _ForceAndMoveCaret(pInput, pNewValue){
		var newValue = pNewValue.toString();
		if(pInput.value != newValue){
			liPos = getCaretPos(pInput).start;
			if(newValue.substr(0,liPos) != pInput.value.substr(0,liPos)){
				liPos--;
			}
			pInput.value = newValue;
			setCaretPos(pInput, liPos, liPos);
			return true;
		}
		return false;	
	}

	function _ValidateNumber(arg, dps, allowNegs, pMin, pMax, p_lFormatType){
		var lsTemp = arg;
		var lFormatType = p_lFormatType ? p_lFormatType : 0;
		
		// store nagative status if it's allowed
		var isNeg = (allowNegs != false && arg.length > 0 && arg.substring(0, 1) == "-");
		
		// if european format, convert decimal point
		if(p_lFormatType == 1){
			lsTemp = lsTemp.replace(/,/gi, '.');
		}
		
		// remove any non numeric characters and allow one decimal point
		lsTemp = lsTemp.replace(/[^\d\.]/g, "");
		var loExp = new RegExp("(\\d*\\.\\d*)\\.([\\d\\.]*)");
		while(loExp.test(lsTemp)){
			lsTemp=lsTemp.replace(loExp, "$1$2");
		}
		
		// remove leading zeroes
		lsTemp = lsTemp.replace(/^0+(\d+)$/, '$1');
		
		// remove unwanted decimal places if required
		if(dps != null){
			if(dps > 0){
				lsTemp=lsTemp.replace(new RegExp("^(\\d*\\.\\d{" + dps + "})\\d$"), "$1");
			}else{
				lsTemp = lsTemp.replace(/[^\d]/g, "");
			}
		}
		
		// reinstate negative status
		if(isNeg){lsTemp = "-" + lsTemp;}
		if(lsTemp.length > 0){
			if(pMin != null && lsTemp - pMin < 0){
				lsTemp = pMin;
			}
			if(pMax != null && pMax - lsTemp < 0){
				lsTemp = pMax;
			}
		}
		
		// if european format, revert decimal point
		if(p_lFormatType == 1){
			lsTemp = lsTemp.toString().replace(/\./, ',');
		}
		
		return lsTemp;
	}
}
function CaretPos(){
	var start = null;
	var end = null;
}
function getCaretPos(pFld){
	var oCaretPos = new CaretPos();
	if(document.selection){
		// mr gates
		pFld.focus();
		var oSel = document.selection.createRange();
		var selectionLength = oSel.text.length;

		oSel.moveStart('character', -pFld.value.length);
		oCaretPos.start = oSel.text.length - selectionLength;
		oCaretPos.end = oSel.text.length;
	}else if(pFld.selectionStart || pFld.selectionStart == '0'){
		oCaretPos.start = pFld.selectionStart;
		oCaretPos.end = pFld.selectionEnd;
	}
	return (oCaretPos);
}
function setCaretPos(pFld, iCaretStart, iCaretEnd){
	if (document.selection){
		pFld.focus();
		var oSel = document.selection.createRange();
		oSel.moveStart ('character', -pFld.value.length);
		oSel.moveEnd ('character', -pFld.value.length);
		if(iCaretEnd != null){
			oSel.moveEnd ('character', iCaretEnd);
		}else{
			oSel.moveEnd ('character', iCaretStart);
		}
		oSel.moveStart ('character', iCaretStart);
		oSel.select();
	}else if(pFld.selectionStart || pFld.selectionStart == '0'){
		pFld.selectionStart = iCaretStart;
		if(iCaretEnd != null){
			pFld.selectionEnd = iCaretEnd;
		}else{
			pFld.selectionEnd = iCaretStart;
		}
		pFld.focus();
	}
}